commit 605530fccc319d2757dc6411883b6d14eef9c532 Author: shenjianZ Date: Sun Apr 26 08:09:15 2026 +0800 initial clean deployment diff --git a/.github/workflows/build-and-push.yml b/.github/workflows/build-and-push.yml new file mode 100644 index 0000000..b0ff0a2 --- /dev/null +++ b/.github/workflows/build-and-push.yml @@ -0,0 +1,88 @@ +name: build-and-push + +on: + push: + branches: ["master", "main"] + tags: ["v*"] + workflow_dispatch: + +jobs: + build-and-push: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + env: + REGISTRY: ${{ secrets.ACR_REGISTRY }} + NAMESPACE: ${{ secrets.IMAGE_NAMESPACE }} + ADMIN_IMAGE_NAME: zzyl-admin + UI_IMAGE_NAME: zzyl-ui + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up JDK 11 + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: "11" + cache: maven + + - name: Build Jar + run: mvn -B clean package -DskipTests + + - name: Prepare image tag + shell: bash + run: | + if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then + echo "IMAGE_TAG=${GITHUB_REF_NAME}" >> "$GITHUB_ENV" + else + echo "IMAGE_TAG=${GITHUB_SHA::7}" >> "$GITHUB_ENV" + fi + echo "ADMIN_IMAGE=${REGISTRY}/${NAMESPACE}/${ADMIN_IMAGE_NAME}" >> "$GITHUB_ENV" + echo "UI_IMAGE=${REGISTRY}/${NAMESPACE}/${UI_IMAGE_NAME}" >> "$GITHUB_ENV" + + - name: Log in to Alibaba Cloud ACR + uses: docker/login-action@v3 + with: + registry: ${{ secrets.ACR_REGISTRY }} + username: ${{ secrets.ACR_USERNAME }} + password: ${{ secrets.ACR_PASSWORD }} + + - name: Build and push admin image + uses: docker/build-push-action@v6 + with: + context: zzyl-admin/target + file: zzyl-admin/Dockerfile + push: true + tags: | + ${{ env.ADMIN_IMAGE }}:${{ env.IMAGE_TAG }} + + - name: Build and push ui image + uses: docker/build-push-action@v6 + with: + context: zzyl-ui + file: zzyl-ui/Dockerfile + push: true + tags: | + ${{ env.UI_IMAGE }}:${{ env.IMAGE_TAG }} + + - name: Push admin latest tag on default branches + if: github.ref_type == 'branch' + uses: docker/build-push-action@v6 + with: + context: zzyl-admin/target + file: zzyl-admin/Dockerfile + push: true + tags: | + ${{ env.ADMIN_IMAGE }}:latest + + - name: Push ui latest tag on default branches + if: github.ref_type == 'branch' + uses: docker/build-push-action@v6 + with: + context: zzyl-ui + file: zzyl-ui/Dockerfile + push: true + tags: | + ${{ env.UI_IMAGE }}:latest diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ed8368a --- /dev/null +++ b/.gitignore @@ -0,0 +1,47 @@ +###################################################################### +# Build Tools + +.gradle +/build/ +!gradle/wrapper/gradle-wrapper.jar + +target/ +!.mvn/wrapper/maven-wrapper.jar + +###################################################################### +# IDE + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### JRebel ### +rebel.xml + +### NetBeans ### +nbproject/private/ +build/* +nbbuild/ +dist/ +nbdist/ +.nb-gradle/ + +###################################################################### +# Others +*.log +*.xml.versionsBackup +*.swp + +!*/build/*.java +!*/build/*.html +!*/build/*.xml diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..63c4cea --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,69 @@ +pipeline { + agent any + options { + timestamps() + } + tools { + maven 'maven' + jdk 'jdk11' + } + stages { + stage('清除工作空间') { + steps { + cleanWs() + } + } + stage('拉取Git代码') { + steps { + echo "正在拉取代码..." + echo "当前分支:${GIT_TAG},当前服务:${services}" + checkout([$class: 'GitSCM', + branches: [[name: GIT_TAG]], + doGenerateSubmoduleConfigurations: false, + extensions: [], + submoduleCfg: [], + userRemoteConfigs: [[credentialsId: 'Gitee_ID', url: GIT_URL]] + ]) + sh "pwd" + } + } + stage('重新Maven打包') { + steps { + script { + echo "正在执行maven打包...." + sh "mvn clean install -DskipTests" + } + } + } + stage('重新构建镜像') { + steps { + echo "当前打镜像tag:${DOCKER_TAG}" + script { + for (ds in services.tokenize(",")) { + sh "pwd" + echo "进入target目录执行镜像打包......" + sh "cd ./${ds}/target/ && docker build -t ${ds}:${DOCKER_TAG} -f ../Dockerfile ." + } + } + } + } + stage('部署服务'){ + steps { + script { + for (ws in services.tokenize(",")) { + sh "pwd" + sh "cd `pwd`" + echo "部署升级:${ws}服务" + sh "chmod +x ./${ws}/deploy.sh && sh ./${ws}/deploy.sh ${ws} ${DOCKER_TAG}" + } + } + } + } + + } + post { + always { + echo '任务构建完毕' + } + } +} \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md new file mode 100644 index 0000000..550ff81 --- /dev/null +++ b/README.md @@ -0,0 +1,89 @@ +

+ logo +

+

Zzyl v3.8.8

+

基于SpringBoot+Vue前后端分离的Java快速开发框架

+

+ + + +

+ + +## 平台简介 + +若依是一套全部开源的快速开发平台,毫无保留给个人及企业免费使用。 + +* 前端采用Vue、Element UI。 +* 后端采用Spring Boot、Spring Security、Redis & Jwt。 +* 权限认证使用Jwt,支持多终端认证系统。 +* 支持加载动态权限菜单,多方式轻松权限控制。 +* 高效率开发,使用代码生成器可以一键生成前后端代码。 +* 提供了技术栈([Vue3](https://v3.cn.vuejs.org) [Element Plus](https://element-plus.org/zh-CN) [Vite](https://cn.vitejs.dev))版本[RuoYi-Vue3](https://github.com/yangzongzhuan/RuoYi-Vue3),保持同步更新。 +* 提供了单应用版本[RuoYi-Vue-fast](https://github.com/yangzongzhuan/RuoYi-Vue-fast),Oracle版本[RuoYi-Vue-Oracle](https://github.com/yangzongzhuan/RuoYi-Vue-Oracle),保持同步更新。 +* 不分离版本,请移步[RuoYi](https://gitee.com/y_project/RuoYi),微服务版本,请移步[RuoYi-Cloud](https://gitee.com/y_project/RuoYi-Cloud) +* 阿里云折扣场:[点我进入](http://aly.ruoyi.vip),腾讯云秒杀场:[点我进入](http://txy.ruoyi.vip)   +* 阿里云优惠券:[点我领取](https://www.aliyun.com/minisite/goods?userCode=brki8iof&share_source=copy_link),腾讯云优惠券:[点我领取](https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console)   + +## 内置功能 + +1. 用户管理:用户是系统操作者,该功能主要完成系统用户配置。 +2. 部门管理:配置系统组织机构(公司、部门、小组),树结构展现支持数据权限。 +3. 岗位管理:配置系统用户所属担任职务。 +4. 菜单管理:配置系统菜单,操作权限,按钮权限标识等。 +5. 角色管理:角色菜单权限分配、设置角色按机构进行数据范围权限划分。 +6. 字典管理:对系统中经常使用的一些较为固定的数据进行维护。 +7. 参数管理:对系统动态配置常用参数。 +8. 通知公告:系统通知公告信息发布维护。 +9. 操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。 +10. 登录日志:系统登录日志记录查询包含登录异常。 +11. 在线用户:当前系统中活跃用户状态监控。 +12. 定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。 +13. 代码生成:前后端代码的生成(java、html、xml、sql)支持CRUD下载 。 +14. 系统接口:根据业务代码自动生成相关的api接口文档。 +15. 服务监控:监视当前系统CPU、内存、磁盘、堆栈等相关信息。 +16. 缓存监控:对系统的缓存信息查询,命令统计等。 +17. 在线构建器:拖动表单元素生成相应的HTML代码。 +18. 连接池监视:监视当前系统数据库连接池状态,可进行分析SQL找出系统性能瓶颈。 + +## 在线体验 + +- admin/admin123 +- 陆陆续续收到一些打赏,为了更好的体验已用于演示服务器升级。谢谢各位小伙伴。 + +## 演示图 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/bin/clean.bat b/bin/clean.bat new file mode 100644 index 0000000..24c0974 --- /dev/null +++ b/bin/clean.bat @@ -0,0 +1,12 @@ +@echo off +echo. +echo [Ϣ] target· +echo. + +%~d0 +cd %~dp0 + +cd .. +call mvn clean + +pause \ No newline at end of file diff --git a/bin/package.bat b/bin/package.bat new file mode 100644 index 0000000..c693ec0 --- /dev/null +++ b/bin/package.bat @@ -0,0 +1,12 @@ +@echo off +echo. +echo [Ϣ] Weḅwar/jarļ +echo. + +%~d0 +cd %~dp0 + +cd .. +call mvn clean package -Dmaven.test.skip=true + +pause \ No newline at end of file diff --git a/bin/run.bat b/bin/run.bat new file mode 100644 index 0000000..a2dead4 --- /dev/null +++ b/bin/run.bat @@ -0,0 +1,14 @@ +@echo off +echo. +echo [Ϣ] ʹJarWeb̡ +echo. + +cd %~dp0 +cd ../zzyl-admin/target + +set JAVA_OPTS=-Xms256m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m + +java -jar %JAVA_OPTS% zzyl-admin.jar + +cd bin +pause \ No newline at end of file diff --git a/deploy/compose/.env.example b/deploy/compose/.env.example new file mode 100644 index 0000000..19ae63f --- /dev/null +++ b/deploy/compose/.env.example @@ -0,0 +1,55 @@ +TZ=Asia/Shanghai + +UI_PORT=80 +APP_PORT=9000 + +ZZYL_ADMIN_IMAGE=registry.cn-hangzhou.aliyuncs.com/example/zzyl-admin:latest +ZZYL_UI_IMAGE=registry.cn-hangzhou.aliyuncs.com/example/zzyl-ui:latest + +MYSQL_PORT=3306 +MYSQL_DATABASE=zzyl +MYSQL_ROOT_PASSWORD=change_me_mysql_root +MYSQL_APP_USER=zzyl +MYSQL_APP_PASSWORD=change_me_mysql_app +MYSQL_URL=jdbc:mysql://zzyl-mysql:3306/zzyl?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai +MYSQL_USERNAME=zzyl +MYSQL_PASSWORD=change_me_mysql_app + +REDIS_PORT=6379 +REDIS_HOST=zzyl-redis +REDIS_PASSWORD=change_me_redis +REDIS_DATABASE=2 + +APP_LOG_DIR=/data/zzyl/logs +APP_PROFILE_DIR=/data/zzyl/uploadPath +RUOYI_PROFILE=/data/zzyl/uploadPath + +TOKEN_SECRET=change_me_token_secret +TOKEN_EXPIRE_TIME=3600 +DRUID_LOGIN_USERNAME=ruoyi +DRUID_LOGIN_PASSWORD=change_me_druid +DEPT_NURSING_ID=201 + +ALIYUN_OSS_DOMAIN=oss-cn-hangzhou.aliyuncs.com +ALIYUN_OSS_ENDPOINT=https://oss-cn-hangzhou.aliyuncs.com +ALIYUN_OSS_BUCKET=change-me-bucket +ALIYUN_OSS_REGION=cn-hangzhou +ALIYUN_OSS_ACCESS_KEY_ID=change_me_oss_key +ALIYUN_OSS_SECRET_ACCESS_KEY=change_me_oss_secret + +BAIDU_ACCESS_KEY=change_me_baidu_key +BAIDU_SECRET_KEY=change_me_baidu_secret +BAIDU_QIANFAN_MODEL=ERNIE-4.0-8K + +WECHAT_MINI_PROGRAM_APP_ID=change_me_wechat_appid +WECHAT_MINI_PROGRAM_SECRET=change_me_wechat_secret + +HUAWEI_CLOUD_AK=change_me_huawei_ak +HUAWEI_CLOUD_SK=change_me_huawei_sk +HUAWEI_CLOUD_REGION_ID=cn-east-3 +HUAWEI_CLOUD_ENDPOINT=change_me_huawei_endpoint +HUAWEI_CLOUD_PROJECT_ID=change_me_huawei_project_id +HUAWEI_CLOUD_AMQP_HOST=change_me_huawei_amqp_host +HUAWEI_CLOUD_AMQP_ACCESS_KEY=change_me_huawei_amqp_access_key +HUAWEI_CLOUD_AMQP_ACCESS_CODE=change_me_huawei_amqp_access_code +HUAWEI_CLOUD_AMQP_QUEUE_NAME=DefaultQueue diff --git a/deploy/compose/docker-compose.app.yml b/deploy/compose/docker-compose.app.yml new file mode 100644 index 0000000..29286de --- /dev/null +++ b/deploy/compose/docker-compose.app.yml @@ -0,0 +1,24 @@ +services: + zzyl-admin: + image: ${ZZYL_ADMIN_IMAGE} + container_name: zzyl-admin + restart: unless-stopped + env_file: + - .env + environment: + TZ: ${TZ} + SPRING_PROFILES_ACTIVE: prod + ports: + - "${APP_PORT}:9000" + volumes: + - ${APP_LOG_DIR}:/home/ruoyi/logs + - ${APP_PROFILE_DIR}:${APP_PROFILE_DIR} + + zzyl-ui: + image: ${ZZYL_UI_IMAGE} + container_name: zzyl-ui + restart: unless-stopped + depends_on: + - zzyl-admin + ports: + - "${UI_PORT}:80" diff --git a/deploy/compose/docker-compose.full.yml b/deploy/compose/docker-compose.full.yml new file mode 100644 index 0000000..a995d6a --- /dev/null +++ b/deploy/compose/docker-compose.full.yml @@ -0,0 +1,63 @@ +services: + mysql: + image: mysql:8.0 + container_name: zzyl-mysql + restart: unless-stopped + environment: + TZ: ${TZ} + MYSQL_DATABASE: ${MYSQL_DATABASE} + MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} + MYSQL_USER: ${MYSQL_APP_USER} + MYSQL_PASSWORD: ${MYSQL_APP_PASSWORD} + ports: + - "${MYSQL_PORT}:3306" + command: + - --default-authentication-plugin=mysql_native_password + - --character-set-server=utf8mb4 + - --collation-server=utf8mb4_general_ci + volumes: + - mysql_data:/var/lib/mysql + + redis: + image: redis:7.2-alpine + container_name: zzyl-redis + restart: unless-stopped + environment: + TZ: ${TZ} + ports: + - "${REDIS_PORT}:6379" + command: > + sh -c "redis-server --appendonly yes --requirepass ${REDIS_PASSWORD}" + volumes: + - redis_data:/data + + zzyl-admin: + image: ${ZZYL_ADMIN_IMAGE} + container_name: zzyl-admin + restart: unless-stopped + env_file: + - .env + depends_on: + - mysql + - redis + environment: + TZ: ${TZ} + SPRING_PROFILES_ACTIVE: prod + ports: + - "${APP_PORT}:9000" + volumes: + - ${APP_LOG_DIR}:/home/ruoyi/logs + - ${APP_PROFILE_DIR}:${APP_PROFILE_DIR} + + zzyl-ui: + image: ${ZZYL_UI_IMAGE} + container_name: zzyl-ui + restart: unless-stopped + depends_on: + - zzyl-admin + ports: + - "${UI_PORT}:80" + +volumes: + mysql_data: + redis_data: diff --git a/deploy/compose/docker-compose.middleware.yml b/deploy/compose/docker-compose.middleware.yml new file mode 100644 index 0000000..2bb8470 --- /dev/null +++ b/deploy/compose/docker-compose.middleware.yml @@ -0,0 +1,46 @@ +services: + mysql: + image: mysql:8.0 + container_name: zzyl-mysql + restart: unless-stopped + environment: + TZ: ${TZ} + MYSQL_DATABASE: ${MYSQL_DATABASE} + MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} + MYSQL_USER: ${MYSQL_APP_USER} + MYSQL_PASSWORD: ${MYSQL_APP_PASSWORD} + ports: + - "${MYSQL_PORT}:3306" + command: + - --default-authentication-plugin=mysql_native_password + - --character-set-server=utf8mb4 + - --collation-server=utf8mb4_general_ci + volumes: + - mysql_data:/var/lib/mysql + healthcheck: + test: ["CMD-SHELL", "mysqladmin ping -uroot -p${MYSQL_ROOT_PASSWORD}"] + interval: 10s + timeout: 5s + retries: 10 + + redis: + image: redis:7.2-alpine + container_name: zzyl-redis + restart: unless-stopped + environment: + TZ: ${TZ} + ports: + - "${REDIS_PORT}:6379" + command: > + sh -c "redis-server --appendonly yes --requirepass ${REDIS_PASSWORD}" + volumes: + - redis_data:/data + healthcheck: + test: ["CMD-SHELL", "redis-cli -a ${REDIS_PASSWORD} ping"] + interval: 10s + timeout: 5s + retries: 10 + +volumes: + mysql_data: + redis_data: diff --git a/deploy/config/application-prod.yml.example b/deploy/config/application-prod.yml.example new file mode 100644 index 0000000..4d2877a --- /dev/null +++ b/deploy/config/application-prod.yml.example @@ -0,0 +1,55 @@ +ruoyi: + profile: /data/zzyl/uploadPath + +spring: + datasource: + druid: + master: + url: jdbc:mysql://zzyl-mysql:3306/zzyl?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai + username: zzyl + password: change_me_mysql_app + statViewServlet: + login-username: ruoyi + login-password: change_me_druid + redis: + host: zzyl-redis + port: 6379 + database: 2 + password: change_me_redis + +token: + secret: change_me_token_secret + expireTime: 3600 + +aliyun: + oss: + domain: oss-cn-hangzhou.aliyuncs.com + endpoint: https://oss-cn-hangzhou.aliyuncs.com + bucket-name: change-me-bucket + region: cn-hangzhou + accessKeyId: change_me_oss_key + secretAccessKey: change_me_oss_secret + +dept: + nursingId: 201 + +baidu: + accessKey: change_me_baidu_key + secretKey: change_me_baidu_secret + qianfanModel: ERNIE-4.0-8K + +wechat: + mini-program: + appId: change_me_wechat_appid + secret: change_me_wechat_secret + +huaweicloud: + ak: change_me_huawei_ak + sk: change_me_huawei_sk + regionId: cn-east-3 + endpoint: change_me_huawei_endpoint + projectId: change_me_huawei_project_id + host: change_me_huawei_amqp_host + accessKey: change_me_huawei_amqp_access_key + accessCode: change_me_huawei_amqp_access_code + queueName: DefaultQueue diff --git a/deploy/nginx/zzyl-api.conf.example b/deploy/nginx/zzyl-api.conf.example new file mode 100644 index 0000000..20acc00 --- /dev/null +++ b/deploy/nginx/zzyl-api.conf.example @@ -0,0 +1,26 @@ +server { + listen 80; + server_name _; + + client_max_body_size 20m; + + location / { + proxy_pass http://127.0.0.1:8080; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + location /prod-api/ { + proxy_pass http://127.0.0.1:9000/; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + } +} diff --git a/doc/若依环境使用手册.docx b/doc/若依环境使用手册.docx new file mode 100644 index 0000000..9e4daef Binary files /dev/null and b/doc/若依环境使用手册.docx differ diff --git a/doc/部署指南.md b/doc/部署指南.md new file mode 100644 index 0000000..c2d6adf --- /dev/null +++ b/doc/部署指南.md @@ -0,0 +1,150 @@ +# 中州养老部署指南 + +## 1. 部署架构 + +本项目按前后端分离部署: + +- 前端:`zzyl-ui`,Vue 2 项目,使用 `pnpm` 构建,打包为 Nginx 镜像。 +- 后端:`zzyl-admin`,Spring Boot 服务,JDK 11,容器内端口 `9000`。 +- 中间件:MySQL 8、Redis 7。 +- CI:GitHub Actions 构建并推送 `zzyl-admin`、`zzyl-ui` 两个镜像。 +- CD:服务器上手动执行 Docker Compose,所有运行时变量统一写在 `deploy/compose/.env`。 + +生产入口为前端服务:`http://服务器IP或域名:${UI_PORT}/`。前端 `/prod-api/` 会由 Nginx 转发到后端 `zzyl-admin:9000`。 + +## 2. 需要准备的材料 + +- Linux 服务器,建议 2 核 4G 以上,已安装 Docker Engine、Docker Compose Plugin、Git、curl。 +- 阿里云 ACR 或其他 Docker Registry,用于保存后端和前端镜像。 +- GitHub Secrets:`ACR_REGISTRY`、`ACR_USERNAME`、`ACR_PASSWORD`、`IMAGE_NAMESPACE`。 +- 域名和 DNS 解析;如对外提供 HTTPS,还需要证书或上层反向代理网关。 +- 数据库初始化脚本:`sql/dev0302.sql`、`sql/quartz.sql`。 +- 阿里云 OSS:Bucket、Endpoint、Region、AccessKeyId、AccessKeySecret。 +- 微信小程序:`appId`、`secret`,并把生产域名加入小程序后台白名单。 +- 华为云 IoTDA/AMQP:AK、SK、ProjectId、Endpoint、RegionId、AMQP Host、AccessKey、AccessCode、QueueName。 +- 百度千帆:AccessKey、SecretKey、模型名。 + +## 3. CI 构建流程 + +工作流文件:`.github/workflows/build-and-push.yml`。 + +触发方式: + +- 推送到 `main` 或 `master`。 +- 推送 `v*` Tag。 +- 在 GitHub Actions 手动执行 `workflow_dispatch`。 + +CI 会执行: + +1. 使用 JDK 11 执行 `mvn -B clean package -DskipTests`。 +2. 基于 `zzyl-admin/Dockerfile` 构建并推送 `zzyl-admin:${tag}`。 +3. 基于 `zzyl-ui/Dockerfile` 使用 `pnpm install --frozen-lockfile && pnpm build:prod` 构建并推送 `zzyl-ui:${tag}`。 +4. 分支构建会额外推送 `latest` 标签。 + +镜像地址示例: + +```text +registry.cn-hangzhou.aliyuncs.com/your-namespace/zzyl-admin:latest +registry.cn-hangzhou.aliyuncs.com/your-namespace/zzyl-ui:latest +``` + +## 4. 服务器目录与环境变量 + +推荐目录: + +```bash +mkdir -p /opt/zzyl/compose /opt/zzyl/sql +mkdir -p /data/zzyl/{logs,uploadPath} +``` + +复制文件到服务器: + +- `deploy/compose/docker-compose.full.yml` 到 `/opt/zzyl/compose/docker-compose.yml` +- `deploy/compose/.env.example` 到 `/opt/zzyl/compose/.env` +- `sql/dev0302.sql` 和 `sql/quartz.sql` 到 `/opt/zzyl/sql` + +编辑 `/opt/zzyl/compose/.env`,至少修改: + +- `ZZYL_ADMIN_IMAGE`、`ZZYL_UI_IMAGE` +- `UI_PORT`,如果宿主机 Nginx 也监听 80,建议改为 `8080` +- `MYSQL_ROOT_PASSWORD`、`MYSQL_APP_PASSWORD`、`MYSQL_PASSWORD` +- `REDIS_PASSWORD` +- `TOKEN_SECRET`、`DRUID_LOGIN_PASSWORD` +- OSS、微信、华为云、百度千帆相关变量 + +注意:`MYSQL_APP_USER/MYSQL_APP_PASSWORD` 必须与 `MYSQL_USERNAME/MYSQL_PASSWORD` 保持一致。 + +## 5. 首次部署 + +进入部署目录: + +```bash +cd /opt/zzyl/compose +docker compose --env-file .env up -d mysql redis +``` + +初始化数据库: + +```bash +set -a +. ./.env +set +a +docker exec -i zzyl-mysql mysql -uroot -p"${MYSQL_ROOT_PASSWORD}" < /opt/zzyl/sql/dev0302.sql +docker exec -i zzyl-mysql mysql -uroot -p"${MYSQL_ROOT_PASSWORD}" zzyl < /opt/zzyl/sql/quartz.sql +``` + +启动完整系统: + +```bash +docker compose --env-file .env pull +docker compose --env-file .env up -d +docker compose --env-file .env ps +``` + +## 6. 进入系统 + +浏览器访问: + +```text +http://服务器IP或域名/ +``` + +如果 `UI_PORT` 不是 `80`,访问: + +```text +http://服务器IP或域名:${UI_PORT}/ +``` + +默认后台账号: + +- 用户名:`admin` +- 密码:`admin123` + +首次登录后请立即修改管理员密码,并检查系统管理、养老业务菜单是否正常显示。 + +## 7. 升级与验证 + +升级: + +```bash +cd /opt/zzyl/compose +docker compose --env-file .env pull +docker compose --env-file .env up -d +docker image prune -f +``` + +验证: + +```bash +docker compose --env-file .env ps +docker logs zzyl-admin --tail 200 +docker logs zzyl-ui --tail 100 +curl -I http://127.0.0.1:${UI_PORT}/ +``` + +常见问题: + +- 前端打不开:检查 `zzyl-ui` 容器、`UI_PORT`、安全组和防火墙。 +- 登录验证码失败:检查 `/prod-api/captchaImage` 是否被 Nginx 转发到后端。 +- 后端启动失败:优先查看 MySQL、Redis、华为云 IoTDA/AMQP、OSS、百度千帆变量。 +- 上传失败:检查 OSS 配置和 `RUOYI_PROFILE=/data/zzyl/uploadPath`。 diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000..f5c85ca Binary files /dev/null and b/favicon.ico differ diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..9ff2c1b --- /dev/null +++ b/pom.xml @@ -0,0 +1,341 @@ + + + 4.0.0 + + com.zzyl + zzyl + 3.8.8 + + zzyl + http://www.ruoyi.vip + 中州养老 + + + 3.8.8 + UTF-8 + UTF-8 + 11 + 3.1.1 + 2.5.15 + 1.2.23 + 1.21 + 3.0.0 + 2.3.3 + 1.4.7 + 2.0.53 + 6.6.5 + 2.13.0 + 4.1.2 + 2.3 + 0.9.1 + + 9.0.96 + 1.2.13 + 5.7.12 + 5.3.39 + 1.18.22 + 3.5.2 + 3.17.4 + 5.8.10 + 2.0.24 + 0.1.1 + + + + + + + org.projectlombok + lombok + ${lombok.version} + + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus-spring-boot.version} + + + com.baomidou + mybatis-plus-annotation + ${mybatis-plus-spring-boot.version} + + + + + com.aliyun.oss + aliyun-sdk-oss + ${aliyun.sdk.oss} + + + + + org.springframework + spring-framework-bom + ${spring-framework.version} + pom + import + + + + + org.springframework.security + spring-security-bom + ${spring-security.version} + pom + import + + + + + org.springframework.boot + spring-boot-dependencies + ${spring-boot.version} + pom + import + + + + + ch.qos.logback + logback-core + ${logback.version} + + + + ch.qos.logback + logback-classic + ${logback.version} + + + + + org.apache.tomcat.embed + tomcat-embed-core + ${tomcat.version} + + + + org.apache.tomcat.embed + tomcat-embed-el + ${tomcat.version} + + + + org.apache.tomcat.embed + tomcat-embed-websocket + ${tomcat.version} + + + + + com.alibaba + druid-spring-boot-starter + ${druid.version} + + + + + eu.bitwalker + UserAgentUtils + ${bitwalker.version} + + + + + com.github.pagehelper + pagehelper-spring-boot-starter + ${pagehelper.boot.version} + + + + + com.github.oshi + oshi-core + ${oshi.version} + + + + + io.springfox + springfox-boot-starter + ${swagger.version} + + + io.swagger + swagger-models + + + + + + + commons-io + commons-io + ${commons.io.version} + + + + + org.apache.poi + poi-ooxml + ${poi.version} + + + + + org.apache.velocity + velocity-engine-core + ${velocity.version} + + + + + com.alibaba.fastjson2 + fastjson2 + ${fastjson.version} + + + + + io.jsonwebtoken + jjwt + ${jwt.version} + + + + + pro.fessional + kaptcha + ${kaptcha.version} + + + + + com.zzyl + zzyl-quartz + ${zzyl.version} + + + + + com.zzyl + zzyl-generator + ${zzyl.version} + + + + + com.zzyl + zzyl-framework + ${zzyl.version} + + + + + com.zzyl + zzyl-system + ${zzyl.version} + + + + + com.zzyl + zzyl-common + ${zzyl.version} + + + + + com.zzyl + zzyl-nursing-platform + ${zzyl.version} + + + + + com.zzyl + zzyl-oss + ${zzyl.version} + + + + + cn.hutool + hutool-all + ${hutool-all.version} + + + + + org.apache.pdfbox + pdfbox + ${pdfbox.version} + + + + + com.baidubce + qianfan + ${qianfan.version} + + + + + + + zzyl-admin + zzyl-framework + zzyl-system + zzyl-quartz + zzyl-generator + zzyl-common + zzyl-nursing-platform + zzyl-oss + + pom + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + ${java.version} + ${java.version} + ${project.build.sourceEncoding} + + + + + + + + public + aliyun nexus + https://maven.aliyun.com/repository/public + + true + + + + + + + public + aliyun nexus + https://maven.aliyun.com/repository/public + + true + + + false + + + + + \ No newline at end of file diff --git a/ry.bat b/ry.bat new file mode 100644 index 0000000..b1d1129 --- /dev/null +++ b/ry.bat @@ -0,0 +1,67 @@ +@echo off + +rem jarƽĿ¼ +set AppName=zzyl-admin.jar + +rem JVM +set JVM_OPTS="-Dname=%AppName% -Duser.timezone=Asia/Shanghai -Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:NewRatio=1 -XX:SurvivorRatio=30 -XX:+UseParallelGC -XX:+UseParallelOldGC" + + +ECHO. + ECHO. [1] %AppName% + ECHO. [2] ر%AppName% + ECHO. [3] %AppName% + ECHO. [4] ״̬ %AppName% + ECHO. [5] +ECHO. + +ECHO.ѡĿ: +set /p ID= + IF "%id%"=="1" GOTO start + IF "%id%"=="2" GOTO stop + IF "%id%"=="3" GOTO restart + IF "%id%"=="4" GOTO status + IF "%id%"=="5" EXIT +PAUSE +:start + for /f "usebackq tokens=1-2" %%a in (`jps -l ^| findstr %AppName%`) do ( + set pid=%%a + set image_name=%%b + ) + if defined pid ( + echo %%is running + PAUSE + ) + +start javaw %JVM_OPTS% -jar %AppName% + +echo starting +echo Start %AppName% success... +goto:eof + +rem stopͨjpspid +:stop + for /f "usebackq tokens=1-2" %%a in (`jps -l ^| findstr %AppName%`) do ( + set pid=%%a + set image_name=%%b + ) + if not defined pid (echo process %AppName% does not exists) else ( + echo prepare to kill %image_name% + echo start kill %pid% ... + rem ݽIDkill + taskkill /f /pid %pid% + ) +goto:eof +:restart + call :stop + call :start +goto:eof +:status + for /f "usebackq tokens=1-2" %%a in (`jps -l ^| findstr %AppName%`) do ( + set pid=%%a + set image_name=%%b + ) + if not defined pid (echo process %AppName% is dead ) else ( + echo %image_name% is running + ) +goto:eof diff --git a/ry.sh b/ry.sh new file mode 100644 index 0000000..33877a4 --- /dev/null +++ b/ry.sh @@ -0,0 +1,86 @@ +#!/bin/sh +# ./ry.sh start 启动 stop 停止 restart 重启 status 状态 +AppName=zzyl-admin.jar + +# JVM参数 +JVM_OPTS="-Dname=$AppName -Duser.timezone=Asia/Shanghai -Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:NewRatio=1 -XX:SurvivorRatio=30 -XX:+UseParallelGC -XX:+UseParallelOldGC" +APP_HOME=`pwd` +LOG_PATH=$APP_HOME/logs/$AppName.log + +if [ "$1" = "" ]; +then + echo -e "\033[0;31m 未输入操作名 \033[0m \033[0;34m {start|stop|restart|status} \033[0m" + exit 1 +fi + +if [ "$AppName" = "" ]; +then + echo -e "\033[0;31m 未输入应用名 \033[0m" + exit 1 +fi + +function start() +{ + PID=`ps -ef |grep java|grep $AppName|grep -v grep|awk '{print $2}'` + + if [ x"$PID" != x"" ]; then + echo "$AppName is running..." + else + nohup java $JVM_OPTS -jar $AppName > /dev/null 2>&1 & + echo "Start $AppName success..." + fi +} + +function stop() +{ + echo "Stop $AppName" + + PID="" + query(){ + PID=`ps -ef |grep java|grep $AppName|grep -v grep|awk '{print $2}'` + } + + query + if [ x"$PID" != x"" ]; then + kill -TERM $PID + echo "$AppName (pid:$PID) exiting..." + while [ x"$PID" != x"" ] + do + sleep 1 + query + done + echo "$AppName exited." + else + echo "$AppName already stopped." + fi +} + +function restart() +{ + stop + sleep 2 + start +} + +function status() +{ + PID=`ps -ef |grep java|grep $AppName|grep -v grep|wc -l` + if [ $PID != 0 ];then + echo "$AppName is running..." + else + echo "$AppName is not running..." + fi +} + +case $1 in + start) + start;; + stop) + stop;; + restart) + restart;; + status) + status;; + *) + +esac diff --git a/sql/dev0224.sql b/sql/dev0224.sql new file mode 100644 index 0000000..554cda0 --- /dev/null +++ b/sql/dev0224.sql @@ -0,0 +1,1048 @@ +-- MySQL dump 10.13 Distrib 8.0.39, for Win64 (x86_64) +-- +-- Host: 192.168.100.168 Database: zzyl +-- ------------------------------------------------------ +-- Server version 8.0.29 + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!50503 SET NAMES utf8mb4 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; + +CREATE DATABASE IF NOT EXISTS `zzyl`; +USE `zzyl`; + +-- +-- Table structure for table `bed` +-- + +DROP TABLE IF EXISTS `bed`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `bed` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '床位ID', + `bed_number` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '床位编号', + `bed_status` int DEFAULT NULL COMMENT '床位状态: 未入住0, 已入住1 ', + `sort` int DEFAULT NULL COMMENT '床位号', + `room_id` bigint DEFAULT NULL COMMENT '房间ID', + `create_time` datetime NOT NULL COMMENT '创建时间', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `create_by` bigint DEFAULT NULL COMMENT '创建人id', + `update_by` bigint DEFAULT NULL COMMENT '更新人id', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE KEY `bed_number` (`bed_number`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=203 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC COMMENT='床位表'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `bed` +-- + +LOCK TABLES `bed` WRITE; +/*!40000 ALTER TABLE `bed` DISABLE KEYS */; +INSERT INTO `bed` VALUES (1,'101-1',1,1,1,'2023-09-26 17:39:53','2023-10-05 15:59:24',1671403256519078138,1671403256519078164,NULL),(2,'102-1',0,1,2,'2023-09-26 17:40:01','2023-10-05 16:00:05',1671403256519078138,1671403256519078164,NULL),(3,'102-2',0,2,2,'2023-09-26 17:40:09','2023-10-05 15:59:45',1671403256519078138,1671403256519078164,NULL),(4,'103-1',0,1,3,'2023-09-26 17:40:42','2023-10-05 16:00:21',1671403256519078138,1671403256519078164,NULL),(5,'104-1',1,1,4,'2023-09-26 17:40:49','2023-09-26 17:45:39',1671403256519078138,1671403256519078138,NULL),(6,'104-2',1,2,4,'2023-09-26 17:40:54','2023-10-20 23:22:12',1671403256519078138,1671403256519078164,NULL),(7,'105-1',0,1,5,'2023-09-26 17:41:09','2023-09-26 17:45:52',1671403256519078138,1671403256519078138,NULL),(8,'106-1',0,1,6,'2023-09-26 17:41:16','2023-09-26 17:45:58',1671403256519078138,1671403256519078138,NULL),(9,'106-2',0,2,6,'2023-09-26 17:41:24','2023-09-26 17:46:04',1671403256519078138,1671403256519078138,NULL),(10,'107-1',0,1,7,'2023-09-26 17:41:32','2023-12-21 09:37:49',1671403256519078138,1671403256519078138,NULL),(11,'201-1',0,1,8,'2023-09-26 17:44:53','2023-10-13 10:40:27',1671403256519078138,1671403256519078164,NULL),(12,'202-1',0,1,9,'2023-09-26 17:46:33','2023-09-26 17:46:33',1671403256519078138,NULL,NULL),(13,'202-2',0,2,9,'2023-09-26 17:46:47','2023-09-26 17:46:47',1671403256519078138,NULL,NULL),(14,'203-1',0,1,10,'2023-09-26 18:43:58','2023-09-26 18:43:58',1671403256519078138,NULL,NULL),(15,'204-1',0,1,11,'2023-09-26 18:44:03','2023-09-26 18:44:03',1671403256519078138,NULL,NULL),(16,'204-2',0,2,11,'2023-09-26 18:44:12','2023-09-26 18:44:12',1671403256519078138,NULL,NULL),(18,'205-1',0,1,12,'2023-09-26 18:44:23','2023-12-20 18:40:07',1671403256519078138,1671403256519078138,NULL),(19,'206-1',0,1,13,'2023-09-26 18:44:36','2023-12-20 21:43:10',1671403256519078138,1671403256519078138,NULL),(20,'206-2',0,2,13,'2023-09-26 18:44:42','2023-09-26 18:44:48',1671403256519078138,1671403256519078138,NULL),(21,'207-1',0,1,14,'2023-09-26 18:45:01','2023-09-26 18:45:01',1671403256519078138,NULL,NULL),(22,'301-2',0,1,15,'2023-09-26 18:45:26','2023-12-26 19:35:06',1671403256519078138,1671403256519078138,NULL),(23,'302-1',0,1,16,'2023-09-26 18:45:31','2023-09-26 18:45:31',1671403256519078138,NULL,NULL),(24,'302-3',0,2,16,'2023-09-26 18:45:39','2023-12-26 19:35:15',1671403256519078138,1671403256519078138,NULL),(25,'303-1',0,1,17,'2023-09-26 18:45:44','2023-09-26 18:45:44',1671403256519078138,NULL,NULL),(27,'304-1',0,1,18,'2023-09-26 18:45:55','2023-09-26 18:45:55',1671403256519078138,NULL,NULL),(28,'304-2',0,2,18,'2023-09-26 18:46:04','2023-09-26 18:46:04',1671403256519078138,NULL,NULL),(29,'305-1',0,1,19,'2023-09-26 18:46:11','2023-12-21 10:04:47',1671403256519078138,1671403256519078138,NULL),(30,'306-1',0,1,20,'2023-09-26 18:46:16','2023-09-26 18:46:16',1671403256519078138,NULL,NULL),(31,'306-2',0,2,20,'2023-09-26 18:46:22','2023-09-26 19:08:50',1671403256519078138,1671403256519078138,NULL),(32,'307-1',0,1,21,'2023-09-26 18:46:29','2023-09-26 18:46:29',1671403256519078138,NULL,NULL),(33,'401-1',0,1,22,'2023-09-26 18:52:14','2023-09-26 18:52:14',1671403256519078138,NULL,NULL),(34,'402-1',0,1,23,'2023-09-26 18:52:22','2023-09-26 18:52:22',1671403256519078138,NULL,NULL),(35,'402-2',0,2,23,'2023-09-26 18:52:35','2023-09-26 18:52:38',1671403256519078138,1671403256519078138,NULL),(36,'403-1',0,1,24,'2023-09-26 18:52:47','2023-09-26 18:52:47',1671403256519078138,NULL,NULL),(37,'404-1',0,1,25,'2023-09-26 18:52:54','2023-09-26 18:52:54',1671403256519078138,NULL,NULL),(38,'404-2',0,2,25,'2023-09-26 18:53:02','2023-09-26 18:53:10',1671403256519078138,1671403256519078138,NULL),(39,'405-1',0,1,26,'2023-09-26 18:53:18','2023-09-26 18:53:18',1671403256519078138,NULL,NULL),(40,'406-1',0,1,27,'2023-09-26 18:53:27','2023-09-26 18:53:27',1671403256519078138,NULL,NULL),(41,'406-2',0,2,27,'2023-09-26 18:53:36','2023-09-26 18:53:36',1671403256519078138,NULL,NULL),(42,'407-1',0,1,28,'2023-09-26 18:53:44','2023-09-26 18:53:44',1671403256519078138,NULL,NULL),(43,'501-1',0,1,29,'2023-09-26 18:55:47','2023-09-26 18:55:47',1671403256519078138,NULL,NULL),(44,'502-1',0,1,31,'2023-09-26 18:55:52','2023-09-26 18:55:52',1671403256519078138,NULL,NULL),(45,'502-2',0,2,31,'2023-09-26 18:56:02','2023-09-26 18:56:02',1671403256519078138,NULL,NULL),(46,'503-1',0,1,32,'2023-09-26 18:56:10','2023-09-26 18:56:10',1671403256519078138,NULL,NULL),(48,'504-1',0,1,33,'2023-09-26 18:56:26','2023-09-26 18:56:26',1671403256519078138,NULL,NULL),(49,'504-2',0,2,33,'2023-09-26 18:56:32','2023-09-26 18:56:32',1671403256519078138,NULL,NULL),(50,'505-1',0,1,34,'2023-09-26 18:56:37','2023-09-26 18:56:37',1671403256519078138,NULL,NULL),(52,'506-1',0,1,35,'2023-09-26 18:56:49','2023-09-26 18:56:49',1671403256519078138,NULL,NULL),(53,'506-2',0,2,35,'2023-09-26 18:56:54','2023-09-26 18:56:54',1671403256519078138,NULL,NULL),(54,'507-1',0,1,36,'2023-09-26 18:57:00','2023-09-26 18:57:00',1671403256519078138,NULL,NULL),(55,'601-1',0,1,37,'2023-09-26 19:05:11','2023-09-28 22:53:28',1671403256519078138,1671403256519078164,NULL),(56,'602-1',0,1,38,'2023-09-26 19:05:16','2023-09-26 19:05:16',1671403256519078138,NULL,NULL),(57,'602-2',0,2,38,'2023-09-26 19:05:24','2023-09-26 19:05:24',1671403256519078138,NULL,NULL),(58,'603-1',0,1,39,'2023-09-26 19:05:29','2023-09-26 19:05:29',1671403256519078138,NULL,NULL),(59,'604-1',0,1,40,'2023-09-26 19:05:33','2023-09-26 19:05:33',1671403256519078138,NULL,NULL),(60,'604-2',0,2,40,'2023-09-26 19:05:38','2023-09-26 19:05:38',1671403256519078138,NULL,NULL),(61,'605-1',0,1,41,'2023-09-26 19:05:43','2023-09-26 19:05:43',1671403256519078138,NULL,NULL),(62,'606-1',0,1,42,'2023-09-26 19:05:48','2023-09-26 19:05:48',1671403256519078138,NULL,NULL),(63,'606-2',0,2,42,'2023-09-26 19:05:54','2023-09-26 19:05:54',1671403256519078138,NULL,NULL),(64,'607-1',0,1,43,'2023-09-26 19:05:59','2023-09-26 19:05:59',1671403256519078138,NULL,NULL),(65,'701-1',0,1,44,'2023-09-26 19:06:10','2023-09-26 19:06:10',1671403256519078138,NULL,NULL),(66,'702-1',0,1,45,'2023-09-26 19:06:14','2023-09-26 19:06:26',1671403256519078138,1671403256519078138,NULL),(68,'702-2',0,2,45,'2023-09-26 19:06:35','2023-09-26 19:06:35',1671403256519078138,NULL,NULL),(69,'703-1',0,1,46,'2023-09-26 19:06:41','2023-09-26 19:06:41',1671403256519078138,NULL,NULL),(70,'704-1',0,1,47,'2023-09-26 19:06:46','2023-12-20 14:28:22',1671403256519078138,1671403256519078138,NULL),(71,'704-2',0,2,47,'2023-09-26 19:06:52','2023-09-26 19:06:57',1671403256519078138,1671403256519078138,NULL),(72,'705-1',0,1,48,'2023-09-26 19:07:04','2023-09-26 19:07:04',1671403256519078138,NULL,NULL),(73,'706-1',0,1,49,'2023-09-26 19:07:10','2023-09-26 19:07:10',1671403256519078138,NULL,NULL),(74,'706-2',0,2,49,'2023-09-26 19:07:14','2023-09-26 19:07:19',1671403256519078138,1671403256519078138,NULL),(75,'707-1',0,1,50,'2023-09-26 19:07:25','2023-09-26 19:07:25',1671403256519078138,NULL,NULL),(76,'801-1',0,1,51,'2023-09-26 19:07:41','2023-09-26 19:07:41',1671403256519078138,NULL,NULL),(77,'803-1',0,1,53,'2023-09-26 19:07:46','2023-09-26 19:07:46',1671403256519078138,NULL,NULL),(78,'805-1',0,1,55,'2023-09-26 19:07:51','2023-09-26 19:07:51',1671403256519078138,NULL,NULL),(79,'807-1',0,1,57,'2023-09-26 19:07:56','2023-09-26 19:07:56',1671403256519078138,1,NULL),(80,'802-1',0,1,52,'2023-09-26 19:08:04','2023-09-26 19:08:04',1671403256519078138,NULL,NULL),(81,'801-2',0,2,52,'2023-09-26 19:08:09','2023-09-26 19:08:09',1671403256519078138,NULL,NULL),(82,'804-1',0,1,54,'2023-09-26 19:08:15','2023-09-26 19:08:15',1671403256519078138,NULL,NULL),(83,'804-2',0,2,54,'2023-09-26 19:08:22','2023-09-26 19:08:22',1671403256519078138,NULL,NULL),(84,'806-1',0,1,56,'2023-09-26 19:08:28','2023-09-26 19:08:28',1671403256519078138,NULL,NULL),(85,'806-2',0,2,56,'2023-09-26 19:08:35','2023-09-26 19:08:35',1671403256519078138,1,NULL),(170,'101-2',1,2,1,'2023-12-21 11:45:09','2023-12-21 11:45:09',1671403256519078138,1,NULL),(171,'103-2',0,1,3,'2023-12-23 16:12:34','2023-12-23 16:22:03',1671403256519078138,1671403256519078138,NULL),(173,'108-1',0,1,67,'2023-12-23 17:59:23','2024-11-03 23:31:50',1671403256519078138,1,NULL),(177,'1011',0,1,74,'2023-12-26 19:32:07','2023-12-26 19:32:07',1671403256519078138,NULL,NULL),(178,'101',0,1,74,'2023-12-26 19:32:15','2023-12-26 19:32:15',1671403256519078138,NULL,NULL),(196,'109-01',0,1,81,'2024-07-31 11:29:18',NULL,1,NULL,NULL),(200,'1201-1',NULL,1,83,'2024-10-04 00:03:31',NULL,1,NULL,NULL),(201,'109-2',NULL,2,81,'2025-01-02 00:37:05',NULL,1,NULL,NULL),(202,'108-2',NULL,2,67,'2025-01-02 00:37:32',NULL,1,NULL,NULL); +/*!40000 ALTER TABLE `bed` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `elder` +-- + +DROP TABLE IF EXISTS `elder`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `elder` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id', + `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '名称', + `image` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '图片', + `id_card_no` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '身份证号', + `sex` int DEFAULT NULL COMMENT '性别(0:女 1:男)', + `status` int NOT NULL DEFAULT '1' COMMENT '状态(0:禁用,1:启用 2:请假 3:退住中 4入住中 5已退住)', + `phone` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '手机号', + `birthday` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '出生日期', + `address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '家庭住址', + `id_card_national_emblem_img` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '身份证国徽面', + `id_card_portrait_img` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '身份证人像面', + `create_time` datetime NOT NULL COMMENT '创建时间', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `create_by` bigint DEFAULT NULL COMMENT '创建人id', + `update_by` bigint DEFAULT NULL COMMENT '更新人id', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '备注', + `bed_number` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '床位编号', + `bed_id` bigint DEFAULT NULL COMMENT '床位id', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE KEY `name_id_card_no` (`name`,`id_card_no`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=329 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC COMMENT='老人表'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `elder` +-- + +LOCK TABLES `elder` WRITE; +/*!40000 ALTER TABLE `elder` DISABLE KEYS */; +INSERT INTO `elder` VALUES (325,'13211223322','https://itheim.oss-cn-beijing.aliyuncs.com/1fb24c20-ec99-44b3-8691-766c5508b347.jpg','132123196712131234',1,1,'13211223322','2024-08-22','13211223322','https://itheim.oss-cn-beijing.aliyuncs.com/b79d8d1e-1015-4d04-83e9-a22d3cc47869.jpg','https://itheim.oss-cn-beijing.aliyuncs.com/07ee1b38-b611-4955-8339-fad02a6d7fc6.jpg','2024-08-27 16:43:20',NULL,1,NULL,NULL,'104-1',5),(326,'李天龙','https://itheim.oss-cn-beijing.aliyuncs.com/8aef5eb9-436f-4ece-b68f-34d957d6b050.png','132123196712131239',1,1,'13222334433','1967-12-13','北京市昌平区','https://itheim.oss-cn-beijing.aliyuncs.com/816d7d6c-d13e-4ec6-9879-68d4f8054935.jpg','https://itheim.oss-cn-beijing.aliyuncs.com/f96f4666-c58f-4f69-bf15-8a521788330f.jpg','2024-08-27 16:50:09',NULL,1,NULL,NULL,'104-2',6),(327,'老李','https://itheim.oss-cn-beijing.aliyuncs.com/1510df9e-fca8-4a35-9443-8e4bacad0e03.png','132123195612132345',1,1,'13212349900','1956-12-13','北京市昌平区','https://itheim.oss-cn-beijing.aliyuncs.com/c265f4da-2197-4cfa-91b8-f627a4875c3c.jpg','https://itheim.oss-cn-beijing.aliyuncs.com/08347a75-7e07-49ed-bfad-65a553517c52.jpg','2024-09-12 18:51:36',NULL,1,NULL,NULL,'101-2',170),(328,'老李头儿',NULL,'410725196904056698',1,1,'15100000001','2023-07-04','知道人色然',NULL,NULL,'2024-09-12 19:10:23',NULL,1,NULL,NULL,'101-1',1); +/*!40000 ALTER TABLE `elder` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `floor` +-- + +DROP TABLE IF EXISTS `floor`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `floor` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id', + `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '名称', + `code` bigint DEFAULT NULL COMMENT '编号', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `create_by` bigint DEFAULT NULL COMMENT '创建人id', + `update_by` bigint DEFAULT NULL COMMENT '更新人id', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE KEY `name` (`name`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=414 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='楼层表'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `floor` +-- + +LOCK TABLES `floor` WRITE; +/*!40000 ALTER TABLE `floor` DISABLE KEYS */; +INSERT INTO `floor` VALUES (1,'1楼',11,'2023-09-26 16:10:27','2024-05-24 17:57:28',1671403256519078153,1,NULL),(2,'2楼',2,'2023-09-26 17:37:20','2023-09-26 17:37:20',1671403256519078138,NULL,NULL),(3,'3楼',3,'2023-09-26 17:37:26','2023-09-26 17:37:26',1671403256519078138,NULL,NULL),(4,'4楼',4,'2023-09-26 17:37:32','2023-09-26 17:37:32',1671403256519078138,NULL,NULL),(5,'5楼',5,'2023-09-26 17:37:38','2023-09-26 17:37:38',1671403256519078138,NULL,NULL),(6,'6楼',6,'2023-09-26 17:37:42','2023-09-26 17:37:59',1671403256519078138,1671403256519078138,NULL),(7,'7楼',7,'2023-09-26 17:37:47','2023-09-26 17:37:52',1671403256519078138,1671403256519078138,NULL),(8,'8楼',8,'2023-09-26 17:38:09','2023-09-26 17:38:09',1671403256519078138,NULL,NULL),(391,'9楼',8,'2023-12-18 14:53:50','2023-12-18 14:53:50',1671403256519078138,NULL,NULL),(401,'10楼',9,'2023-12-26 19:29:54','2023-12-27 10:15:34',1671403256519078138,1671403256519078138,NULL),(406,'12楼',1,'2024-05-27 14:07:32','2024-05-27 14:14:46',1,1,NULL); +/*!40000 ALTER TABLE `floor` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `gen_table` +-- + +DROP TABLE IF EXISTS `gen_table`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `gen_table` ( + `table_id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号', + `table_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '表名称', + `table_comment` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '表描述', + `sub_table_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '关联子表的表名', + `sub_table_fk_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '子表关联的外键名', + `class_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '实体类名称', + `tpl_category` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT 'crud' COMMENT '使用的模板(crud单表操作 tree树表操作)', + `tpl_web_type` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '前端模板类型(element-ui模版 element-plus模版)', + `package_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '生成包路径', + `module_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '生成模块名', + `business_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '生成业务名', + `function_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '生成功能名', + `function_author` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '生成功能作者', + `gen_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '生成代码方式(0zip压缩包 1自定义路径)', + `gen_path` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '/' COMMENT '生成路径(不填默认项目路径)', + `options` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '其它生成选项', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '创建者', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '更新者', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`table_id`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='代码生成业务表'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `gen_table` +-- + +LOCK TABLES `gen_table` WRITE; +/*!40000 ALTER TABLE `gen_table` DISABLE KEYS */; +/*!40000 ALTER TABLE `gen_table` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `gen_table_column` +-- + +DROP TABLE IF EXISTS `gen_table_column`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `gen_table_column` ( + `column_id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号', + `table_id` bigint DEFAULT NULL COMMENT '归属表编号', + `column_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '列名称', + `column_comment` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '列描述', + `column_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '列类型', + `java_type` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'JAVA类型', + `java_field` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'JAVA字段名', + `is_pk` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '是否主键(1是)', + `is_increment` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '是否自增(1是)', + `is_required` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '是否必填(1是)', + `is_insert` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '是否为插入字段(1是)', + `is_edit` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '是否编辑字段(1是)', + `is_list` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '是否列表字段(1是)', + `is_query` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '是否查询字段(1是)', + `query_type` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT 'EQ' COMMENT '查询方式(等于、不等于、大于、小于、范围)', + `html_type` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '显示类型(文本框、文本域、下拉框、复选框、单选框、日期控件)', + `dict_type` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '字典类型', + `sort` int DEFAULT NULL COMMENT '排序', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '创建者', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '更新者', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`column_id`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=262 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='代码生成业务表字段'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `gen_table_column` +-- + +LOCK TABLES `gen_table_column` WRITE; +/*!40000 ALTER TABLE `gen_table_column` DISABLE KEYS */; +/*!40000 ALTER TABLE `gen_table_column` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `nursing_elder` +-- + +DROP TABLE IF EXISTS `nursing_elder`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `nursing_elder` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id', + `nursing_id` bigint DEFAULT NULL COMMENT '护理员id', + `elder_id` bigint DEFAULT NULL COMMENT '老人id', + `create_time` datetime NOT NULL COMMENT '创建时间', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `create_by` bigint DEFAULT NULL COMMENT '创建人id', + `update_by` bigint DEFAULT NULL COMMENT '更新人id', + `remark` varchar(255) DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`id`), + UNIQUE KEY `nursing_id` (`nursing_id`,`elder_id`) +) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC COMMENT='护理员老人关联表'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `nursing_elder` +-- + +LOCK TABLES `nursing_elder` WRITE; +/*!40000 ALTER TABLE `nursing_elder` DISABLE KEYS */; +INSERT INTO `nursing_elder` VALUES (2,101,327,'2025-01-02 01:07:42',NULL,1,NULL,NULL),(3,102,327,'2025-01-02 01:07:42',NULL,1,NULL,NULL),(4,101,328,'2025-01-02 01:07:42',NULL,1,NULL,NULL),(5,102,328,'2025-01-02 01:07:42',NULL,1,NULL,NULL),(6,101,325,'2025-01-02 01:07:48',NULL,1,NULL,NULL),(7,101,326,'2025-01-02 01:07:48',NULL,1,NULL,NULL); +/*!40000 ALTER TABLE `nursing_elder` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `nursing_level` +-- + +DROP TABLE IF EXISTS `nursing_level`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `nursing_level` ( + `id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '等级名称', + `lplan_id` int NOT NULL COMMENT '护理计划ID', + `fee` decimal(10,2) NOT NULL COMMENT '护理费用', + `status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '状态(0:禁用,1:启用)', + `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '等级说明', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `create_by` bigint DEFAULT NULL COMMENT '创建人id', + `update_by` bigint DEFAULT NULL COMMENT '更新人id', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '备注', + `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE KEY `name` (`name`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=79 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC COMMENT='护理等级表'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `nursing_level` +-- + +LOCK TABLES `nursing_level` WRITE; +/*!40000 ALTER TABLE `nursing_level` DISABLE KEYS */; +INSERT INTO `nursing_level` VALUES (76,'2号护理等级',134,1500.00,1,'1223','2024-08-14 16:33:16',NULL,NULL,NULL,'2024-08-29 16:57:23'),(77,'1号护理计划',133,2000.00,1,'1223','2024-08-20 11:18:21',NULL,NULL,NULL,'2024-08-29 16:57:05'),(78,'3号护理等级',135,3000.00,1,'无','2024-08-29 16:58:00',NULL,NULL,NULL,'2024-08-29 08:56:55'); +/*!40000 ALTER TABLE `nursing_level` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `nursing_plan` +-- + +DROP TABLE IF EXISTS `nursing_plan`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `nursing_plan` ( + `id` int NOT NULL AUTO_INCREMENT COMMENT '编号', + `sort_no` int DEFAULT NULL COMMENT '排序号', + `plan_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '名称', + `status` tinyint NOT NULL DEFAULT '0' COMMENT '状态 0禁用 1启用', + `create_time` datetime NOT NULL COMMENT '创建时间', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `create_by` bigint DEFAULT NULL COMMENT '创建人id', + `update_by` bigint DEFAULT NULL COMMENT '更新人id', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE KEY `plan_name` (`plan_name`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=136 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC COMMENT='护理计划表'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `nursing_plan` +-- + +LOCK TABLES `nursing_plan` WRITE; +/*!40000 ALTER TABLE `nursing_plan` DISABLE KEYS */; +INSERT INTO `nursing_plan` VALUES (133,1,'1号护理计划',1,'2024-08-19 19:17:31',NULL,NULL,NULL,NULL),(134,1,'2号护理计划',1,'2024-08-19 19:36:10',NULL,NULL,NULL,NULL),(135,1,'3号护理计划',1,'2024-08-29 16:56:39',NULL,NULL,NULL,NULL); +/*!40000 ALTER TABLE `nursing_plan` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `nursing_project` +-- + +DROP TABLE IF EXISTS `nursing_project`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `nursing_project` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号', + `name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '名称', + `order_no` int DEFAULT NULL COMMENT '排序号', + `unit` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '单位', + `price` decimal(10,2) DEFAULT NULL COMMENT '价格', + `image` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '图片', + `nursing_requirement` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '护理要求', + `status` int NOT NULL DEFAULT '1' COMMENT '状态(0:禁用,1:启用)', + `create_by` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '创建人', + `update_by` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '更新人', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '备注', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE KEY `name` (`name`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC COMMENT='护理项目表'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `nursing_project` +-- + +LOCK TABLES `nursing_project` WRITE; +/*!40000 ALTER TABLE `nursing_project` DISABLE KEYS */; +INSERT INTO `nursing_project` VALUES (1,'修剪指甲',1,'次',10.00,'https://itheim.oss-cn-beijing.aliyuncs.com/b6631465-1684-41fe-8ccd-0b027cb91e90.png','无',1,'1',NULL,NULL,'2024-08-29 16:51:50','2024-08-29 08:50:45'),(2,'衣物清洁',1,'件',5.00,'https://itheim.oss-cn-beijing.aliyuncs.com/41fc58d3-0627-4fa9-8459-906599aa1efa.png','无',1,'1',NULL,NULL,'2024-08-29 16:52:27','2024-08-29 08:51:21'),(3,'整理床铺',1,'次',15.00,'https://itheim.oss-cn-beijing.aliyuncs.com/e611fcc9-dc45-49ac-abeb-f2ea99c2cffc.png','无',1,'1',NULL,NULL,'2024-08-29 16:52:52','2024-08-29 08:51:46'),(4,'助餐',1,'餐',15.00,'https://itheim.oss-cn-beijing.aliyuncs.com/d91ba642-88e5-4c3d-8e50-a681ae3300e5.png','无',1,'1',NULL,NULL,'2024-08-29 16:53:29','2024-08-29 08:52:24'),(5,'助浴',1,'次',40.00,'https://itheim.oss-cn-beijing.aliyuncs.com/125df948-7646-4fce-b322-1db0a84856e7.png','无',1,'1',NULL,NULL,'2024-08-29 16:53:51','2024-08-29 08:52:46'),(6,'洗头',1,'次',20.00,'https://itheim.oss-cn-beijing.aliyuncs.com/a38883fc-870b-40ff-a256-54ce2fc17af9.png','无',1,'1',NULL,NULL,'2024-08-29 16:54:22','2024-08-29 08:53:17'),(7,'洗脸',1,'次',15.00,'https://itheim.oss-cn-beijing.aliyuncs.com/95b0ad37-5d61-4ec2-a961-d6fb691a18f0.png','无',1,'1',NULL,NULL,'2024-08-29 16:54:45','2024-08-29 08:53:40'),(8,'洗脚',1,'次',20.00,'https://itheim.oss-cn-beijing.aliyuncs.com/8437eb2d-3ea5-4eee-9d78-017bc8b3a66e.png','无',1,'1',NULL,NULL,'2024-08-29 16:55:08','2024-08-29 08:54:03'),(9,'心理咨询',1,'小时',80.00,'https://itheim.oss-cn-beijing.aliyuncs.com/dc004cc2-688c-4d22-8fbc-8e923219a2bd.png','无',1,'1',NULL,NULL,'2024-08-29 16:55:37','2024-08-29 08:54:32'); +/*!40000 ALTER TABLE `nursing_project` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `nursing_project_plan` +-- + +DROP TABLE IF EXISTS `nursing_project_plan`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `nursing_project_plan` ( + `id` int NOT NULL AUTO_INCREMENT, + `plan_id` int NOT NULL COMMENT '计划id', + `project_id` int NOT NULL COMMENT '项目id', + `execute_time` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '计划执行时间', + `execute_cycle` int NOT NULL COMMENT '执行周期 0 天 1 周 2月', + `execute_frequency` int NOT NULL COMMENT '执行频次', + `create_time` datetime NOT NULL COMMENT '创建时间', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `create_by` bigint DEFAULT NULL COMMENT '创建人id', + `update_by` bigint DEFAULT NULL COMMENT '更新人id', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=1743 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC COMMENT='护理计划和项目关联表'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `nursing_project_plan` +-- + +LOCK TABLES `nursing_project_plan` WRITE; +/*!40000 ALTER TABLE `nursing_project_plan` DISABLE KEYS */; +INSERT INTO `nursing_project_plan` VALUES (1736,133,87,'19:16:49',1,7,'2024-08-19 11:28:43',NULL,NULL,NULL,NULL),(1737,133,85,'19:28:34',1,1,'2024-08-19 11:28:43',NULL,NULL,NULL,NULL),(1739,135,1,'16:55:58',2,1,'2024-08-29 08:55:34',NULL,NULL,NULL,NULL),(1740,135,5,'16:56:09',0,1,'2024-08-29 08:55:34',NULL,NULL,NULL,NULL),(1741,135,4,'08:00:00',0,1,'2024-08-29 08:55:34',NULL,NULL,NULL,NULL),(1742,134,1,'19:28:45',0,1,'2024-10-03 14:50:59',NULL,NULL,NULL,NULL); +/*!40000 ALTER TABLE `nursing_project_plan` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `nursing_task` +-- + +DROP TABLE IF EXISTS `nursing_task`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `nursing_task` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id', + `nursing_id` varchar(50) DEFAULT NULL COMMENT '护理员id', + `project_id` int NOT NULL COMMENT '项目id', + `project_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '护理项目名称', + `elder_id` bigint DEFAULT NULL COMMENT '老人id', + `elder_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '老人姓名', + `bed_number` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '床位编号', + `estimated_server_time` datetime DEFAULT NULL COMMENT '预计服务时间', + `real_server_time` datetime DEFAULT NULL COMMENT '实际服务时间', + `mark` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '执行记录', + `cancel_reason` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '取消原因', + `status` int DEFAULT NULL COMMENT '状态 1待执行 2已执行 3已关闭 ', + `task_image` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '执行图片', + `create_time` datetime NOT NULL COMMENT '创建时间', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `create_by` bigint DEFAULT NULL COMMENT '创建人id', + `update_by` bigint DEFAULT NULL COMMENT '更新人id', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC COMMENT='护理任务表'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `nursing_task` +-- + +LOCK TABLES `nursing_task` WRITE; +/*!40000 ALTER TABLE `nursing_task` DISABLE KEYS */; +/*!40000 ALTER TABLE `nursing_task` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `room` +-- + +DROP TABLE IF EXISTS `room`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `room` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '房间编号', + `sort` int DEFAULT NULL COMMENT '排序号', + `type_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '房间类型名称', + `floor_id` bigint DEFAULT NULL COMMENT '楼层id', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `is_deleted` tinyint(1) DEFAULT '0' COMMENT '是否删除', + `create_by` bigint DEFAULT NULL COMMENT '创建人id', + `update_by` bigint DEFAULT NULL COMMENT '更新人id', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE KEY `code` (`code`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=89 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC COMMENT='房间表'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `room` +-- + +LOCK TABLES `room` WRITE; +/*!40000 ALTER TABLE `room` DISABLE KEYS */; +INSERT INTO `room` VALUES (1,'101',1,'豪华单人间',1,'2023-09-26 17:38:25','2023-12-23 16:19:55',0,1671403256519078138,1671403256519078138,NULL),(2,'102',2,'普通双人间',1,'2023-09-26 17:38:32','2023-09-26 17:38:32',0,1671403256519078138,NULL,NULL),(3,'103',3,'普通单人间',1,'2023-09-26 17:38:41','2023-09-26 17:38:41',0,1671403256519078138,NULL,NULL),(4,'104',4,'豪华双人间',1,'2023-09-26 17:38:48','2023-09-26 17:38:48',0,1671403256519078138,NULL,NULL),(5,'105',5,'豪华单人间',1,'2023-09-26 17:38:55','2023-09-26 17:38:55',0,1671403256519078138,NULL,NULL),(6,'106',6,'双人套房',1,'2023-09-26 17:39:05','2023-09-26 17:39:05',0,1671403256519078138,NULL,NULL),(7,'107',7,'单人套房',1,'2023-09-26 17:39:13','2023-09-26 17:39:13',0,1671403256519078138,NULL,NULL),(8,'201',1,'特护房',2,'2023-09-26 17:42:02','2023-09-26 17:42:02',0,1671403256519078138,NULL,NULL),(9,'202',2,'普通双人间',2,'2023-09-26 17:42:08','2023-09-26 17:42:08',0,1671403256519078138,NULL,NULL),(10,'203',3,'普通单人间',2,'2023-09-26 17:42:15','2023-09-26 17:42:15',0,1671403256519078138,NULL,NULL),(11,'204',4,'豪华双人间',2,'2023-09-26 17:42:22','2023-09-26 17:42:22',0,1671403256519078138,NULL,NULL),(12,'205',5,'豪华单人间',2,'2023-09-26 17:42:30','2023-09-26 17:42:30',0,1671403256519078138,NULL,NULL),(13,'206',6,'双人套房',2,'2023-09-26 17:42:41','2023-09-26 17:42:41',0,1671403256519078138,NULL,NULL),(14,'207',7,'单人套房',2,'2023-09-26 17:42:48','2023-09-26 17:42:48',0,1671403256519078138,NULL,NULL),(15,'301',1,'特护房',3,'2023-09-26 17:43:54','2023-09-26 17:43:54',0,1671403256519078138,NULL,NULL),(16,'302',2,'普通双人间',3,'2023-09-26 17:44:01','2023-09-26 17:44:01',0,1671403256519078138,NULL,NULL),(17,'303',3,'普通单人间',3,'2023-09-26 17:44:09','2023-09-26 17:44:09',0,1671403256519078138,NULL,NULL),(18,'304',4,'豪华双人间',3,'2023-09-26 17:44:17','2023-09-26 17:44:17',0,1671403256519078138,NULL,NULL),(19,'305',5,'豪华单人间',3,'2023-09-26 17:44:24','2023-09-26 17:44:24',0,1671403256519078138,NULL,NULL),(20,'306',6,'双人套房',3,'2023-09-26 17:44:33','2023-09-26 17:44:33',0,1671403256519078138,NULL,NULL),(21,'307',7,'单人套房',3,'2023-09-26 17:44:42','2023-09-26 17:44:42',0,1671403256519078138,NULL,NULL),(22,'401',1,'特护房',4,'2023-09-26 18:51:10','2023-09-26 18:51:10',0,1671403256519078138,NULL,NULL),(23,'402',2,'普通双人间',4,'2023-09-26 18:51:17','2023-09-26 18:51:17',0,1671403256519078138,NULL,NULL),(24,'403',3,'普通单人间',4,'2023-09-26 18:51:23','2023-09-26 18:51:23',0,1671403256519078138,NULL,NULL),(25,'404',4,'豪华双人间',4,'2023-09-26 18:51:32','2023-09-26 18:51:32',0,1671403256519078138,NULL,NULL),(26,'405',5,'豪华单人间',4,'2023-09-26 18:51:42','2023-09-26 18:51:42',0,1671403256519078138,NULL,NULL),(27,'406',6,'双人套房',4,'2023-09-26 18:51:54','2023-09-26 18:51:54',0,1671403256519078138,NULL,NULL),(28,'407',7,'单人套房',4,'2023-09-26 18:52:03','2023-09-26 18:52:03',0,1671403256519078138,NULL,NULL),(29,'501',1,'特护房',5,'2023-09-26 18:53:54','2023-09-26 18:53:54',0,1671403256519078138,NULL,NULL),(31,'502',2,'普通双人间',5,'2023-09-26 18:54:05','2023-09-26 18:54:05',0,1671403256519078138,NULL,NULL),(32,'503',3,'普通单人间',5,'2023-09-26 18:54:12','2023-09-26 18:54:12',0,1671403256519078138,NULL,NULL),(33,'504',4,'豪华双人间',5,'2023-09-26 18:54:20','2023-09-26 18:54:20',0,1671403256519078138,NULL,NULL),(34,'505',5,'豪华单人间',5,'2023-09-26 18:54:28','2023-09-26 18:54:28',0,1671403256519078138,NULL,NULL),(35,'506',6,'双人套房',5,'2023-09-26 18:54:37','2023-09-26 18:54:37',0,1671403256519078138,NULL,NULL),(36,'507',7,'单人套房',5,'2023-09-26 18:54:47','2023-09-26 18:54:47',0,1671403256519078138,NULL,NULL),(37,'601',1,'特护房',6,'2023-09-26 18:57:14','2023-09-26 18:57:14',0,1671403256519078138,NULL,NULL),(38,'602',2,'普通双人间',6,'2023-09-26 18:57:20','2023-09-26 18:57:20',0,1671403256519078138,NULL,NULL),(39,'603',3,'普通单人间',6,'2023-09-26 18:57:28','2023-09-26 18:57:28',0,1671403256519078138,NULL,NULL),(40,'604',4,'豪华双人间',6,'2023-09-26 18:57:36','2023-09-26 18:57:36',0,1671403256519078138,NULL,NULL),(41,'605',5,'豪华单人间',6,'2023-09-26 19:01:36','2023-09-26 19:01:36',0,1671403256519078138,NULL,NULL),(42,'606',6,'双人套房',6,'2023-09-26 19:01:45','2023-09-26 19:01:45',0,1671403256519078138,NULL,NULL),(43,'607',7,'单人套房',6,'2023-09-26 19:01:54','2023-09-26 19:01:54',0,1671403256519078138,NULL,NULL),(44,'701',1,'特护房',7,'2023-09-26 19:02:13','2023-09-26 19:02:13',0,1671403256519078138,NULL,NULL),(45,'702',2,'普通双人间',7,'2023-09-26 19:02:20','2023-09-26 19:02:20',0,1671403256519078138,NULL,NULL),(46,'703',3,'普通单人间',7,'2023-09-26 19:02:28','2023-09-26 19:02:28',0,1671403256519078138,NULL,NULL),(47,'704',4,'豪华双人间',7,'2023-09-26 19:02:49','2023-09-26 19:02:49',0,1671403256519078138,NULL,NULL),(48,'705',5,'豪华单人间',7,'2023-09-26 19:03:00','2023-09-26 19:03:00',0,1671403256519078138,NULL,NULL),(49,'706',6,'双人套房',7,'2023-09-26 19:03:07','2023-09-26 19:03:07',0,1671403256519078138,NULL,NULL),(50,'707',7,'单人套房',7,'2023-09-26 19:03:15','2023-09-26 19:03:15',0,1671403256519078138,NULL,NULL),(51,'801',1,'特护房',8,'2023-09-26 19:03:49','2023-09-26 19:03:49',0,1671403256519078138,NULL,NULL),(52,'802',2,'普通双人间',8,'2023-09-26 19:03:57','2023-09-26 19:03:57',0,1671403256519078138,NULL,NULL),(53,'803',3,'普通单人间',8,'2023-09-26 19:04:04','2023-09-26 19:04:04',0,1671403256519078138,NULL,NULL),(54,'804',4,'豪华双人间',8,'2023-09-26 19:04:13','2023-09-26 19:04:13',0,1671403256519078138,NULL,NULL),(55,'805',5,'豪华单人间',8,'2023-09-26 19:04:45','2023-09-26 19:04:45',0,1671403256519078138,NULL,NULL),(56,'806',6,'双人套房',8,'2023-09-26 19:04:52','2023-09-26 19:04:52',0,1671403256519078138,NULL,NULL),(57,'807',7,'单人套房',8,'2023-09-26 19:05:00','2023-09-26 19:05:00',0,1671403256519078138,NULL,NULL),(67,'108',1,'普通单人间',1,'2023-12-23 16:12:46','2023-12-23 17:08:47',0,1671403256519078138,1671403256519078138,NULL),(81,'109',1,'单人套房',1,'2024-05-27 10:28:37',NULL,0,1,NULL,NULL),(83,'1201',1,'双人套房',406,'2024-05-27 14:14:54',NULL,0,1,NULL,NULL),(86,'102-2',1,'豪华单人间',406,'2024-08-22 18:49:21',NULL,0,1,NULL,NULL); +/*!40000 ALTER TABLE `room` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `room_type` +-- + +DROP TABLE IF EXISTS `room_type`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `room_type` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '房型名称', + `bed_count` int NOT NULL DEFAULT '0' COMMENT '床位数量', + `price` decimal(10,2) NOT NULL COMMENT '床位费用', + `introduction` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '介绍', + `photo` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '照片', + `status` tinyint NOT NULL COMMENT '状态,0:禁用,1:启用', + `create_time` datetime NOT NULL COMMENT '创建时间', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `create_by` bigint DEFAULT NULL COMMENT '创建人id', + `update_by` bigint DEFAULT NULL COMMENT '更新人id', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE KEY `name` (`name`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=117 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC COMMENT='房型表'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `room_type` +-- + +LOCK TABLES `room_type` WRITE; +/*!40000 ALTER TABLE `room_type` DISABLE KEYS */; +INSERT INTO `room_type` VALUES (1,'单人套房',0,4000.00,'宽敞舒适的套房,配备独立卫生间和基本生活设施,满足独自居住的需求,提供私密性和舒适度','https://yjy-slwl-oss.oss-cn-hangzhou.aliyuncs.com/e2f1031b-e23e-4379-95d4-ce8fe382f58f.png',1,'2023-09-26 15:57:50','2024-10-03 23:54:34',1671403256519078153,1,NULL),(2,'双人套房',0,6000.00,'适合夫妻或朋友两人居住的套房,设有独立卫生间和基本生活设施,提供共享空间和私密性','https://yjy-slwl-oss.oss-cn-hangzhou.aliyuncs.com/ff84c185-2e28-431c-951d-d004cc2d5bdc.png',1,'2023-09-26 15:58:51','2023-09-26 15:58:51',1671403256519078153,NULL,NULL),(3,'豪华单人间',0,3000.00,'豪华装修的单人房间,提供舒适的居住环境和高品质的服务,设计精美,配备独立卫生间和必需设施','https://yjy-slwl-oss.oss-cn-hangzhou.aliyuncs.com/d803832c-5b93-4cae-ba95-aeb52ab0c5e0.png',1,'2023-09-26 15:59:33','2023-09-26 15:59:33',1671403256519078153,NULL,NULL),(4,'豪华双人间',0,4500.00,'精心装修的双人房间,提供舒适和豪华的居住环境,配备独立卫生间和高品质的家具','https://yjy-slwl-oss.oss-cn-hangzhou.aliyuncs.com/c3522da7-4c5c-48d2-94f9-9f0b95a048d2.png',1,'2023-09-26 16:00:03','2024-08-22 16:12:20',1671403256519078153,1,NULL),(5,'普通单人间',0,2000.00,'简洁实用的单人房间,提供基本的居住设施和舒适度,适合独自居住的老年人,提供相对经济实惠的居住选择','https://yjy-slwl-oss.oss-cn-hangzhou.aliyuncs.com/1a330b1c-b0a1-463d-8d9a-221ef17c314f.png',1,'2023-09-26 16:00:27','2023-09-26 16:00:27',1671403256519078153,NULL,NULL),(103,'我的房型设置',0,6000.00,'啊傻瓜按个按个','https://yjy-slwl-oss.oss-cn-hangzhou.aliyuncs.com/9c4a9926-2f58-4306-a8c5-122adb8e700e.jpeg',1,'2023-12-25 16:04:00','2023-12-25 16:04:00',1671403256519078138,NULL,NULL),(110,'测试修改',5,1000.00,'12312312312312312312312312312312312312312312312312','https://yjy-slwl-oss.oss-cn-hangzhou.aliyuncs.com/00167193-00f1-49a6-85e5-74dd0b93819e.png',1,'2023-12-27 00:07:07','2024-08-22 19:05:53',1671403256519078138,1,NULL),(115,'测试新增',10,3500.00,'水电费方式','https://itheim.oss-cn-beijing.aliyuncs.com/8fe7b29d-fce0-4201-becb-0586e8284a9d.png',1,'2024-08-22 19:06:33','2024-08-22 19:06:41',1,1,'是否'),(116,'标准双人间',10,1500.00,'123','https://itheim.oss-cn-beijing.aliyuncs.com/91c4a814-efd5-4093-a5ac-963b41047019.png',1,'2024-09-12 22:52:36','2024-09-12 22:55:10',1,1,'123'); +/*!40000 ALTER TABLE `room_type` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `sys_config` +-- + +DROP TABLE IF EXISTS `sys_config`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `sys_config` ( + `config_id` int NOT NULL AUTO_INCREMENT COMMENT '参数主键', + `config_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '参数名称', + `config_key` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '参数键名', + `config_value` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '参数键值', + `config_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT 'N' COMMENT '系统内置(Y是 N否)', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '创建者', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '更新者', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`config_id`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=100 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='参数配置表'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `sys_config` +-- + +LOCK TABLES `sys_config` WRITE; +/*!40000 ALTER TABLE `sys_config` DISABLE KEYS */; +INSERT INTO `sys_config` VALUES (1,'主框架页-默认皮肤样式名称','sys.index.skinName','skin-blue','Y','admin','2024-08-14 02:48:24','',NULL,'蓝色 skin-blue、绿色 skin-green、紫色 skin-purple、红色 skin-red、黄色 skin-yellow'),(2,'用户管理-账号初始密码','sys.user.initPassword','123456','Y','admin','2024-08-14 02:48:24','',NULL,'初始化密码 123456'),(3,'主框架页-侧边栏主题','sys.index.sideTheme','theme-dark','Y','admin','2024-08-14 02:48:24','',NULL,'深色主题theme-dark,浅色主题theme-light'),(4,'账号自助-验证码开关','sys.account.captchaEnabled','true','Y','admin','2024-08-14 02:48:24','',NULL,'是否开启验证码功能(true开启,false关闭)'),(5,'账号自助-是否开启用户注册功能','sys.account.registerUser','false','Y','admin','2024-08-14 02:48:24','',NULL,'是否开启注册用户功能(true开启,false关闭)'),(6,'用户登录-黑名单列表','sys.login.blackIPList','','Y','admin','2024-08-14 02:48:24','',NULL,'设置登录IP黑名单限制,多个匹配项以;分隔,支持匹配(*通配、网段)'); +/*!40000 ALTER TABLE `sys_config` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `sys_dept` +-- + +DROP TABLE IF EXISTS `sys_dept`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `sys_dept` ( + `dept_id` bigint NOT NULL AUTO_INCREMENT COMMENT '部门id', + `parent_id` bigint DEFAULT '0' COMMENT '父部门id', + `ancestors` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '祖级列表', + `dept_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '部门名称', + `order_num` int DEFAULT '0' COMMENT '显示顺序', + `leader` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '负责人', + `phone` varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '联系电话', + `email` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '邮箱', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '部门状态(0正常 1停用)', + `del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '创建者', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '更新者', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`dept_id`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=204 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='部门表'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `sys_dept` +-- + +LOCK TABLES `sys_dept` WRITE; +/*!40000 ALTER TABLE `sys_dept` DISABLE KEYS */; +INSERT INTO `sys_dept` VALUES (100,0,'0','智慧养老院',0,'若依','15888888888','ry@qq.com','0','0','admin','2024-08-14 02:48:23','admin','2024-10-18 10:08:30'),(101,100,'0,100','高层办公室',1,'若依','15888888888','ry@qq.com','0','0','admin','2024-08-14 02:48:23','admin','2024-10-18 10:08:40'),(102,100,'0,100','财务部',2,'','','','0','0','admin','2024-08-14 02:48:23','admin','2024-10-18 10:11:02'),(103,101,'0,100,101','院长办公室',1,'若依','15888888888','ry@qq.com','0','0','admin','2024-08-14 02:48:23','admin','2024-10-18 10:08:55'),(104,101,'0,100,101','市场部门',2,'若依','15888888888','ry@qq.com','0','2','admin','2024-08-14 02:48:23','',NULL),(105,101,'0,100,101','测试部门',3,'若依','15888888888','ry@qq.com','0','2','admin','2024-08-14 02:48:23','',NULL),(106,101,'0,100,101','财务部门',4,'若依','15888888888','ry@qq.com','0','2','admin','2024-08-14 02:48:23','',NULL),(107,101,'0,100,101','运维部门',5,'若依','15888888888','ry@qq.com','0','2','admin','2024-08-14 02:48:23','',NULL),(108,102,'0,100,102','市场部门',1,'若依','15888888888','ry@qq.com','0','2','admin','2024-08-14 02:48:23','',NULL),(109,102,'0,100,102','财务部门',2,'若依','15888888888','ry@qq.com','0','2','admin','2024-08-14 02:48:23','',NULL),(200,100,'0,100','行政部',3,NULL,NULL,NULL,'0','0','admin','2024-10-18 10:10:44','',NULL),(201,100,'0,100','护理部',4,NULL,NULL,NULL,'0','0','admin','2024-10-18 10:10:55','',NULL),(202,100,'0,100','后勤部',5,NULL,NULL,NULL,'0','0','admin','2024-10-18 10:11:15','',NULL),(203,100,'0,100','销售部',6,NULL,NULL,NULL,'0','0','admin','2024-10-18 10:11:24','',NULL); +/*!40000 ALTER TABLE `sys_dept` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `sys_dict_data` +-- + +DROP TABLE IF EXISTS `sys_dict_data`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `sys_dict_data` ( + `dict_code` bigint NOT NULL AUTO_INCREMENT COMMENT '字典编码', + `dict_sort` int DEFAULT '0' COMMENT '字典排序', + `dict_label` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '字典标签', + `dict_value` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '字典键值', + `dict_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '字典类型', + `css_class` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '样式属性(其他样式扩展)', + `list_class` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '表格回显样式', + `is_default` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT 'N' COMMENT '是否默认(Y是 N否)', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '状态(0正常 1停用)', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '创建者', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '更新者', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`dict_code`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=109 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='字典数据表'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `sys_dict_data` +-- + +LOCK TABLES `sys_dict_data` WRITE; +/*!40000 ALTER TABLE `sys_dict_data` DISABLE KEYS */; +INSERT INTO `sys_dict_data` VALUES (1,1,'男','0','sys_user_sex','','','Y','0','admin','2024-08-14 02:48:24','',NULL,'性别男'),(2,2,'女','1','sys_user_sex','','','N','0','admin','2024-08-14 02:48:24','',NULL,'性别女'),(3,3,'未知','2','sys_user_sex','','','N','0','admin','2024-08-14 02:48:24','',NULL,'性别未知'),(4,1,'显示','0','sys_show_hide','','primary','Y','0','admin','2024-08-14 02:48:24','',NULL,'显示菜单'),(5,2,'隐藏','1','sys_show_hide','','danger','N','0','admin','2024-08-14 02:48:24','',NULL,'隐藏菜单'),(6,1,'正常','0','sys_normal_disable','','primary','Y','0','admin','2024-08-14 02:48:24','',NULL,'正常状态'),(7,2,'停用','1','sys_normal_disable','','danger','N','0','admin','2024-08-14 02:48:24','',NULL,'停用状态'),(8,1,'正常','0','sys_job_status','','primary','Y','0','admin','2024-08-14 02:48:24','',NULL,'正常状态'),(9,2,'暂停','1','sys_job_status','','danger','N','0','admin','2024-08-14 02:48:24','',NULL,'停用状态'),(10,1,'默认','DEFAULT','sys_job_group','','','Y','0','admin','2024-08-14 02:48:24','',NULL,'默认分组'),(11,2,'系统','SYSTEM','sys_job_group','','','N','0','admin','2024-08-14 02:48:24','',NULL,'系统分组'),(12,1,'是','Y','sys_yes_no','','primary','Y','0','admin','2024-08-14 02:48:24','',NULL,'系统默认是'),(13,2,'否','N','sys_yes_no','','danger','N','0','admin','2024-08-14 02:48:24','',NULL,'系统默认否'),(14,1,'通知','1','sys_notice_type','','warning','Y','0','admin','2024-08-14 02:48:24','',NULL,'通知'),(15,2,'公告','2','sys_notice_type','','success','N','0','admin','2024-08-14 02:48:24','',NULL,'公告'),(16,1,'正常','0','sys_notice_status','','primary','Y','0','admin','2024-08-14 02:48:24','',NULL,'正常状态'),(17,2,'关闭','1','sys_notice_status','','danger','N','0','admin','2024-08-14 02:48:24','',NULL,'关闭状态'),(18,99,'其他','0','sys_oper_type','','info','N','0','admin','2024-08-14 02:48:24','',NULL,'其他操作'),(19,1,'新增','1','sys_oper_type','','info','N','0','admin','2024-08-14 02:48:24','',NULL,'新增操作'),(20,2,'修改','2','sys_oper_type','','info','N','0','admin','2024-08-14 02:48:24','',NULL,'修改操作'),(21,3,'删除','3','sys_oper_type','','danger','N','0','admin','2024-08-14 02:48:24','',NULL,'删除操作'),(22,4,'授权','4','sys_oper_type','','primary','N','0','admin','2024-08-14 02:48:24','',NULL,'授权操作'),(23,5,'导出','5','sys_oper_type','','warning','N','0','admin','2024-08-14 02:48:24','',NULL,'导出操作'),(24,6,'导入','6','sys_oper_type','','warning','N','0','admin','2024-08-14 02:48:24','',NULL,'导入操作'),(25,7,'强退','7','sys_oper_type','','danger','N','0','admin','2024-08-14 02:48:24','',NULL,'强退操作'),(26,8,'生成代码','8','sys_oper_type','','warning','N','0','admin','2024-08-14 02:48:24','',NULL,'生成操作'),(27,9,'清空数据','9','sys_oper_type','','danger','N','0','admin','2024-08-14 02:48:24','',NULL,'清空操作'),(28,1,'成功','0','sys_common_status','','primary','N','0','admin','2024-08-14 02:48:24','',NULL,'正常状态'),(29,2,'失败','1','sys_common_status','','danger','N','0','admin','2024-08-14 02:48:24','',NULL,'停用状态'),(100,0,'启用','1','nursing_project_status',NULL,'default','N','0','admin','2024-08-18 02:41:15','',NULL,NULL),(101,0,'禁用','0','nursing_project_status',NULL,'default','N','0','admin','2024-08-18 02:41:30','',NULL,NULL),(103,0,'启用','1','nursing_plan_status',NULL,'default','N','0','admin','2024-08-19 11:00:04','',NULL,NULL),(104,0,'禁用','2','nursing_plan_status',NULL,'default','N','0','admin','2024-08-19 11:00:10','',NULL,NULL),(105,0,'启用','1','nursing_level_status',NULL,'default','N','0','admin','2024-08-20 03:04:14','',NULL,NULL),(106,0,'禁用','0','nursing_level_status',NULL,'default','N','0','admin','2024-08-20 03:04:21','',NULL,NULL),(107,0,'已入住','0','admission_status',NULL,'default','N','0','admin','2024-08-31 03:20:26','',NULL,NULL),(108,0,'未入住','1','admission_status',NULL,'default','N','0','admin','2024-08-31 03:20:35','',NULL,NULL); +/*!40000 ALTER TABLE `sys_dict_data` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `sys_dict_type` +-- + +DROP TABLE IF EXISTS `sys_dict_type`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `sys_dict_type` ( + `dict_id` bigint NOT NULL AUTO_INCREMENT COMMENT '字典主键', + `dict_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '字典名称', + `dict_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '字典类型', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '状态(0正常 1停用)', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '创建者', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '更新者', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`dict_id`) USING BTREE, + UNIQUE KEY `dict_type` (`dict_type`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=104 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='字典类型表'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `sys_dict_type` +-- + +LOCK TABLES `sys_dict_type` WRITE; +/*!40000 ALTER TABLE `sys_dict_type` DISABLE KEYS */; +INSERT INTO `sys_dict_type` VALUES (1,'用户性别','sys_user_sex','0','admin','2024-08-14 02:48:24','',NULL,'用户性别列表'),(2,'菜单状态','sys_show_hide','0','admin','2024-08-14 02:48:24','',NULL,'菜单状态列表'),(3,'系统开关','sys_normal_disable','0','admin','2024-08-14 02:48:24','',NULL,'系统开关列表'),(4,'任务状态','sys_job_status','0','admin','2024-08-14 02:48:24','',NULL,'任务状态列表'),(5,'任务分组','sys_job_group','0','admin','2024-08-14 02:48:24','',NULL,'任务分组列表'),(6,'系统是否','sys_yes_no','0','admin','2024-08-14 02:48:24','',NULL,'系统是否列表'),(7,'通知类型','sys_notice_type','0','admin','2024-08-14 02:48:24','',NULL,'通知类型列表'),(8,'通知状态','sys_notice_status','0','admin','2024-08-14 02:48:24','',NULL,'通知状态列表'),(9,'操作类型','sys_oper_type','0','admin','2024-08-14 02:48:24','',NULL,'操作类型列表'),(10,'系统状态','sys_common_status','0','admin','2024-08-14 02:48:24','',NULL,'登录状态列表'),(100,'护理项目状态','nursing_project_status','0','admin','2024-08-18 02:40:48','',NULL,NULL),(101,'护理计划状态','nursing_plan_status','0','admin','2024-08-19 10:59:40','',NULL,NULL),(102,'护理等级状态','nursing_level_status','0','admin','2024-08-20 03:04:03','',NULL,NULL),(103,'健康评估-入住状态','admission_status','0','admin','2024-08-31 03:19:57','',NULL,NULL); +/*!40000 ALTER TABLE `sys_dict_type` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `sys_job` +-- + +DROP TABLE IF EXISTS `sys_job`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `sys_job` ( + `job_id` bigint NOT NULL AUTO_INCREMENT COMMENT '任务ID', + `job_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '任务名称', + `job_group` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'DEFAULT' COMMENT '任务组名', + `invoke_target` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '调用目标字符串', + `cron_expression` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'cron执行表达式', + `misfire_policy` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '3' COMMENT '计划执行错误策略(1立即执行 2执行一次 3放弃执行)', + `concurrent` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '1' COMMENT '是否并发执行(0允许 1禁止)', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '状态(0正常 1暂停)', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '创建者', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '更新者', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '备注信息', + PRIMARY KEY (`job_id`,`job_name`,`job_group`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=100 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='定时任务调度表'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `sys_job` +-- + +LOCK TABLES `sys_job` WRITE; +/*!40000 ALTER TABLE `sys_job` DISABLE KEYS */; +INSERT INTO `sys_job` VALUES (1,'系统默认(无参)','DEFAULT','ryTask.ryNoParams','0/10 * * * * ?','3','1','1','admin','2024-08-14 02:48:24','',NULL,''),(2,'系统默认(有参)','DEFAULT','ryTask.ryParams(\'ry\')','0/15 * * * * ?','3','1','1','admin','2024-08-14 02:48:24','',NULL,''),(3,'系统默认(多参)','DEFAULT','ryTask.ryMultipleParams(\'ry\', true, 2000L, 316.50D, 100)','0/20 * * * * ?','3','1','1','admin','2024-08-14 02:48:24','',NULL,''); +/*!40000 ALTER TABLE `sys_job` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `sys_job_log` +-- + +DROP TABLE IF EXISTS `sys_job_log`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `sys_job_log` ( + `job_log_id` bigint NOT NULL AUTO_INCREMENT COMMENT '任务日志ID', + `job_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '任务名称', + `job_group` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '任务组名', + `invoke_target` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '调用目标字符串', + `job_message` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '日志信息', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '执行状态(0正常 1失败)', + `exception_info` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '异常信息', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + PRIMARY KEY (`job_log_id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='定时任务调度日志表'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `sys_job_log` +-- + +LOCK TABLES `sys_job_log` WRITE; +/*!40000 ALTER TABLE `sys_job_log` DISABLE KEYS */; +/*!40000 ALTER TABLE `sys_job_log` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `sys_logininfor` +-- + +DROP TABLE IF EXISTS `sys_logininfor`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `sys_logininfor` ( + `info_id` bigint NOT NULL AUTO_INCREMENT COMMENT '访问ID', + `user_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '用户账号', + `ipaddr` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '登录IP地址', + `login_location` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '登录地点', + `browser` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '浏览器类型', + `os` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '操作系统', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '登录状态(0成功 1失败)', + `msg` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '提示消息', + `login_time` datetime DEFAULT NULL COMMENT '访问时间', + PRIMARY KEY (`info_id`) USING BTREE, + KEY `idx_sys_logininfor_s` (`status`) USING BTREE, + KEY `idx_sys_logininfor_lt` (`login_time`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=202 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='系统访问记录'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `sys_logininfor` +-- + +LOCK TABLES `sys_logininfor` WRITE; +/*!40000 ALTER TABLE `sys_logininfor` DISABLE KEYS */; +INSERT INTO `sys_logininfor` VALUES (100,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-14 02:54:16'),(101,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','退出成功','2024-08-14 03:20:32'),(102,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-14 03:20:40'),(103,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-14 04:21:52'),(104,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-14 07:36:43'),(105,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-14 07:49:48'),(106,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-14 08:24:37'),(107,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','退出成功','2024-08-14 08:32:48'),(108,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-14 08:32:52'),(109,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','1','验证码错误','2024-08-18 01:47:10'),(110,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-18 01:47:14'),(111,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','1','验证码错误','2024-08-18 02:40:15'),(112,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-18 02:40:18'),(113,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-18 03:46:09'),(114,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-18 04:34:20'),(115,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-18 06:15:19'),(116,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-18 07:08:20'),(117,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-18 11:24:56'),(118,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-19 02:22:04'),(119,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-19 07:14:04'),(120,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-19 08:46:55'),(121,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-19 10:58:07'),(122,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-19 12:19:50'),(123,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-19 13:26:44'),(124,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-19 14:33:19'),(125,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-20 01:53:18'),(126,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','退出成功','2024-08-20 01:54:45'),(127,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-20 01:54:49'),(128,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-20 12:16:31'),(129,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-20 13:07:33'),(130,'admin','127.0.0.1','内网IP','Chrome 12','Windows 10','0','登录成功','2024-08-21 02:37:32'),(131,'admin','127.0.0.1','内网IP','Chrome 12','Windows 10','0','登录成功','2024-08-21 03:14:36'),(132,'admin','127.0.0.1','内网IP','Chrome 12','Windows 10','0','登录成功','2024-08-21 06:08:52'),(133,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-22 03:36:06'),(134,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-22 03:47:06'),(135,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-22 06:36:32'),(136,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-22 06:44:22'),(137,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-22 06:48:14'),(138,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-22 08:09:53'),(139,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-22 08:37:07'),(140,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-22 10:37:38'),(141,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-22 12:05:05'),(142,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-22 12:15:51'),(143,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-23 12:20:22'),(144,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-23 14:07:06'),(145,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','1','验证码已失效','2024-08-24 02:40:19'),(146,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-24 02:40:25'),(147,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-24 03:43:54'),(148,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-24 06:32:35'),(149,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','退出成功','2024-08-24 06:36:05'),(150,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-24 06:36:09'),(151,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-24 07:53:34'),(152,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-25 07:54:03'),(153,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-25 08:31:27'),(154,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-25 12:23:25'),(155,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-26 06:07:27'),(156,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-26 08:40:31'),(157,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-26 09:50:34'),(158,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-26 11:26:27'),(159,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-26 12:07:34'),(160,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-26 14:22:24'),(161,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-26 15:18:25'),(162,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-27 02:17:54'),(163,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-27 03:41:31'),(164,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','1','验证码错误','2024-08-27 06:25:06'),(165,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','1','验证码错误','2024-08-27 06:25:10'),(166,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-27 06:25:13'),(167,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-27 07:32:00'),(168,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-27 08:39:36'),(169,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-29 06:38:53'),(170,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-29 06:46:34'),(171,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-29 06:51:27'),(172,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-29 07:34:49'),(173,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-29 08:17:29'),(174,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','1','验证码已失效','2024-08-30 06:29:43'),(175,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-30 06:29:45'),(176,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-30 07:12:44'),(177,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-30 08:07:00'),(178,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-30 08:53:46'),(179,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-08-31 02:24:01'),(180,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-09-01 02:38:35'),(181,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-09-01 03:15:35'),(182,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-09-01 03:51:04'),(183,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-09-01 06:29:01'),(184,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-09-01 11:47:50'),(185,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-09-02 11:33:09'),(186,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-09-11 16:03:21'),(187,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-09-11 17:25:25'),(188,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-09-11 23:17:18'),(189,'admin','172.16.43.100','内网IP','Chrome 12','Windows 10','0','登录成功','2024-09-12 18:42:50'),(190,'lisi','127.0.0.1','内网IP','Chrome 11','Windows 10','1','用户不存在/密码错误','2024-09-12 18:47:41'),(191,'admin','127.0.0.1','内网IP','Chrome 11','Windows 10','0','登录成功','2024-09-12 18:47:57'),(192,'admin','172.16.43.100','内网IP','Chrome 11','Windows 10','0','登录成功','2024-09-12 18:59:12'),(193,'admin','172.16.43.190','内网IP','Chrome 11','Windows 10','0','登录成功','2024-09-12 19:26:05'),(194,'admin','127.0.0.1','内网IP','Chrome 12','Windows 10','0','登录成功','2024-10-03 13:22:01'),(195,'admin','127.0.0.1','内网IP','Chrome 12','Windows 10','0','登录成功','2024-10-03 13:34:31'),(196,'admin','127.0.0.1','内网IP','Chrome 12','Windows 10','0','登录成功','2024-10-06 14:45:19'),(197,'admin','127.0.0.1','内网IP','Chrome 13','Windows 10','0','登录成功','2024-11-03 15:21:21'),(198,'admin','127.0.0.1','内网IP','Chrome 13','Windows 10','0','退出成功','2024-11-03 15:34:59'),(199,'admin','127.0.0.1','内网IP','Chrome 13','Windows 10','0','登录成功','2024-11-03 15:35:03'),(200,'admin','127.0.0.1','内网IP','Chrome 13','Windows 10','0','退出成功','2024-11-03 16:12:11'),(201,'admin','127.0.0.1','内网IP','Chrome 13','Windows 10','0','登录成功','2024-11-03 16:12:14'); +/*!40000 ALTER TABLE `sys_logininfor` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `sys_menu` +-- + +DROP TABLE IF EXISTS `sys_menu`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `sys_menu` ( + `menu_id` bigint NOT NULL AUTO_INCREMENT COMMENT '菜单ID', + `menu_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '菜单名称', + `parent_id` bigint DEFAULT '0' COMMENT '父菜单ID', + `order_num` int DEFAULT '0' COMMENT '显示顺序', + `path` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '路由地址', + `component` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '组件路径', + `query` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '路由参数', + `route_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '路由名称', + `is_frame` int DEFAULT '1' COMMENT '是否为外链(0是 1否)', + `is_cache` int DEFAULT '0' COMMENT '是否缓存(0缓存 1不缓存)', + `menu_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '菜单类型(M目录 C菜单 F按钮)', + `visible` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '菜单状态(0显示 1隐藏)', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '菜单状态(0正常 1停用)', + `perms` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '权限标识', + `icon` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '#' COMMENT '菜单图标', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '创建者', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '更新者', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '备注', + PRIMARY KEY (`menu_id`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=2053 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='菜单权限表'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `sys_menu` +-- + +LOCK TABLES `sys_menu` WRITE; +/*!40000 ALTER TABLE `sys_menu` DISABLE KEYS */; +INSERT INTO `sys_menu` VALUES (1,'系统管理',0,6,'system',NULL,'','',1,0,'M','0','0','','system','admin','2024-08-14 02:48:23','admin','2024-08-29 06:40:54','系统管理目录'),(2,'系统监控',0,7,'monitor',NULL,'','',1,0,'M','0','0','','monitor','admin','2024-08-14 02:48:23','admin','2024-08-29 06:41:07','系统监控目录'),(3,'系统工具',0,8,'tool',NULL,'','',1,0,'M','0','0','','tool','admin','2024-08-14 02:48:23','admin','2024-08-29 06:41:14','系统工具目录'),(4,'若依官网',0,4,'http://ruoyi.vip',NULL,'','',0,0,'M','1','0','','guide','admin','2024-08-14 02:48:23','admin','2024-08-20 01:57:10','若依官网地址'),(100,'用户管理',1,1,'user','system/user/index','','',1,0,'C','0','0','system:user:list','user','admin','2024-08-14 02:48:23','',NULL,'用户管理菜单'),(101,'角色管理',1,2,'role','system/role/index','','',1,0,'C','0','0','system:role:list','peoples','admin','2024-08-14 02:48:23','',NULL,'角色管理菜单'),(102,'菜单管理',1,3,'menu','system/menu/index','','',1,0,'C','0','0','system:menu:list','tree-table','admin','2024-08-14 02:48:23','',NULL,'菜单管理菜单'),(103,'部门管理',1,4,'dept','system/dept/index','','',1,0,'C','0','0','system:dept:list','tree','admin','2024-08-14 02:48:23','',NULL,'部门管理菜单'),(104,'岗位管理',1,5,'post','system/post/index','','',1,0,'C','0','0','system:post:list','post','admin','2024-08-14 02:48:23','',NULL,'岗位管理菜单'),(105,'字典管理',1,6,'dict','system/dict/index','','',1,0,'C','0','0','system:dict:list','dict','admin','2024-08-14 02:48:23','',NULL,'字典管理菜单'),(106,'参数设置',1,7,'config','system/config/index','','',1,0,'C','0','0','system:config:list','edit','admin','2024-08-14 02:48:23','',NULL,'参数设置菜单'),(107,'通知公告',1,8,'notice','system/notice/index','','',1,0,'C','0','0','system:notice:list','message','admin','2024-08-14 02:48:23','',NULL,'通知公告菜单'),(108,'日志管理',1,9,'log','','','',1,0,'M','0','0','','log','admin','2024-08-14 02:48:23','',NULL,'日志管理菜单'),(109,'在线用户',2,1,'online','monitor/online/index','','',1,0,'C','0','0','monitor:online:list','online','admin','2024-08-14 02:48:23','',NULL,'在线用户菜单'),(110,'定时任务',2,2,'job','monitor/job/index','','',1,0,'C','0','0','monitor:job:list','job','admin','2024-08-14 02:48:23','',NULL,'定时任务菜单'),(111,'数据监控',2,3,'druid','monitor/druid/index','','',1,0,'C','0','0','monitor:druid:list','druid','admin','2024-08-14 02:48:23','',NULL,'数据监控菜单'),(112,'服务监控',2,4,'server','monitor/server/index','','',1,0,'C','0','0','monitor:server:list','server','admin','2024-08-14 02:48:23','',NULL,'服务监控菜单'),(113,'缓存监控',2,5,'cache','monitor/cache/index','','',1,0,'C','0','0','monitor:cache:list','redis','admin','2024-08-14 02:48:23','',NULL,'缓存监控菜单'),(114,'缓存列表',2,6,'cacheList','monitor/cache/list','','',1,0,'C','0','0','monitor:cache:list','redis-list','admin','2024-08-14 02:48:23','',NULL,'缓存列表菜单'),(115,'表单构建',3,1,'build','tool/build/index','','',1,0,'C','0','0','tool:build:list','build','admin','2024-08-14 02:48:23','',NULL,'表单构建菜单'),(116,'代码生成',3,2,'gen','tool/gen/index','','',1,0,'C','0','0','tool:gen:list','code','admin','2024-08-14 02:48:23','',NULL,'代码生成菜单'),(117,'系统接口',3,3,'swagger','tool/swagger/index','','',1,0,'C','0','0','tool:swagger:list','swagger','admin','2024-08-14 02:48:23','',NULL,'系统接口菜单'),(500,'操作日志',108,1,'operlog','monitor/operlog/index','','',1,0,'C','0','0','monitor:operlog:list','form','admin','2024-08-14 02:48:23','',NULL,'操作日志菜单'),(501,'登录日志',108,2,'logininfor','monitor/logininfor/index','','',1,0,'C','0','0','monitor:logininfor:list','logininfor','admin','2024-08-14 02:48:23','',NULL,'登录日志菜单'),(1000,'用户查询',100,1,'','','','',1,0,'F','0','0','system:user:query','#','admin','2024-08-14 02:48:23','',NULL,''),(1001,'用户新增',100,2,'','','','',1,0,'F','0','0','system:user:add','#','admin','2024-08-14 02:48:23','',NULL,''),(1002,'用户修改',100,3,'','','','',1,0,'F','0','0','system:user:edit','#','admin','2024-08-14 02:48:23','',NULL,''),(1003,'用户删除',100,4,'','','','',1,0,'F','0','0','system:user:remove','#','admin','2024-08-14 02:48:23','',NULL,''),(1004,'用户导出',100,5,'','','','',1,0,'F','0','0','system:user:export','#','admin','2024-08-14 02:48:23','',NULL,''),(1005,'用户导入',100,6,'','','','',1,0,'F','0','0','system:user:import','#','admin','2024-08-14 02:48:23','',NULL,''),(1006,'重置密码',100,7,'','','','',1,0,'F','0','0','system:user:resetPwd','#','admin','2024-08-14 02:48:23','',NULL,''),(1007,'角色查询',101,1,'','','','',1,0,'F','0','0','system:role:query','#','admin','2024-08-14 02:48:23','',NULL,''),(1008,'角色新增',101,2,'','','','',1,0,'F','0','0','system:role:add','#','admin','2024-08-14 02:48:23','',NULL,''),(1009,'角色修改',101,3,'','','','',1,0,'F','0','0','system:role:edit','#','admin','2024-08-14 02:48:23','',NULL,''),(1010,'角色删除',101,4,'','','','',1,0,'F','0','0','system:role:remove','#','admin','2024-08-14 02:48:23','',NULL,''),(1011,'角色导出',101,5,'','','','',1,0,'F','0','0','system:role:export','#','admin','2024-08-14 02:48:23','',NULL,''),(1012,'菜单查询',102,1,'','','','',1,0,'F','0','0','system:menu:query','#','admin','2024-08-14 02:48:23','',NULL,''),(1013,'菜单新增',102,2,'','','','',1,0,'F','0','0','system:menu:add','#','admin','2024-08-14 02:48:23','',NULL,''),(1014,'菜单修改',102,3,'','','','',1,0,'F','0','0','system:menu:edit','#','admin','2024-08-14 02:48:23','',NULL,''),(1015,'菜单删除',102,4,'','','','',1,0,'F','0','0','system:menu:remove','#','admin','2024-08-14 02:48:23','',NULL,''),(1016,'部门查询',103,1,'','','','',1,0,'F','0','0','system:dept:query','#','admin','2024-08-14 02:48:23','',NULL,''),(1017,'部门新增',103,2,'','','','',1,0,'F','0','0','system:dept:add','#','admin','2024-08-14 02:48:23','',NULL,''),(1018,'部门修改',103,3,'','','','',1,0,'F','0','0','system:dept:edit','#','admin','2024-08-14 02:48:23','',NULL,''),(1019,'部门删除',103,4,'','','','',1,0,'F','0','0','system:dept:remove','#','admin','2024-08-14 02:48:23','',NULL,''),(1020,'岗位查询',104,1,'','','','',1,0,'F','0','0','system:post:query','#','admin','2024-08-14 02:48:23','',NULL,''),(1021,'岗位新增',104,2,'','','','',1,0,'F','0','0','system:post:add','#','admin','2024-08-14 02:48:23','',NULL,''),(1022,'岗位修改',104,3,'','','','',1,0,'F','0','0','system:post:edit','#','admin','2024-08-14 02:48:23','',NULL,''),(1023,'岗位删除',104,4,'','','','',1,0,'F','0','0','system:post:remove','#','admin','2024-08-14 02:48:23','',NULL,''),(1024,'岗位导出',104,5,'','','','',1,0,'F','0','0','system:post:export','#','admin','2024-08-14 02:48:23','',NULL,''),(1025,'字典查询',105,1,'#','','','',1,0,'F','0','0','system:dict:query','#','admin','2024-08-14 02:48:23','',NULL,''),(1026,'字典新增',105,2,'#','','','',1,0,'F','0','0','system:dict:add','#','admin','2024-08-14 02:48:23','',NULL,''),(1027,'字典修改',105,3,'#','','','',1,0,'F','0','0','system:dict:edit','#','admin','2024-08-14 02:48:23','',NULL,''),(1028,'字典删除',105,4,'#','','','',1,0,'F','0','0','system:dict:remove','#','admin','2024-08-14 02:48:23','',NULL,''),(1029,'字典导出',105,5,'#','','','',1,0,'F','0','0','system:dict:export','#','admin','2024-08-14 02:48:23','',NULL,''),(1030,'参数查询',106,1,'#','','','',1,0,'F','0','0','system:config:query','#','admin','2024-08-14 02:48:23','',NULL,''),(1031,'参数新增',106,2,'#','','','',1,0,'F','0','0','system:config:add','#','admin','2024-08-14 02:48:23','',NULL,''),(1032,'参数修改',106,3,'#','','','',1,0,'F','0','0','system:config:edit','#','admin','2024-08-14 02:48:23','',NULL,''),(1033,'参数删除',106,4,'#','','','',1,0,'F','0','0','system:config:remove','#','admin','2024-08-14 02:48:23','',NULL,''),(1034,'参数导出',106,5,'#','','','',1,0,'F','0','0','system:config:export','#','admin','2024-08-14 02:48:23','',NULL,''),(1035,'公告查询',107,1,'#','','','',1,0,'F','0','0','system:notice:query','#','admin','2024-08-14 02:48:23','',NULL,''),(1036,'公告新增',107,2,'#','','','',1,0,'F','0','0','system:notice:add','#','admin','2024-08-14 02:48:23','',NULL,''),(1037,'公告修改',107,3,'#','','','',1,0,'F','0','0','system:notice:edit','#','admin','2024-08-14 02:48:23','',NULL,''),(1038,'公告删除',107,4,'#','','','',1,0,'F','0','0','system:notice:remove','#','admin','2024-08-14 02:48:23','',NULL,''),(1039,'操作查询',500,1,'#','','','',1,0,'F','0','0','monitor:operlog:query','#','admin','2024-08-14 02:48:23','',NULL,''),(1040,'操作删除',500,2,'#','','','',1,0,'F','0','0','monitor:operlog:remove','#','admin','2024-08-14 02:48:23','',NULL,''),(1041,'日志导出',500,3,'#','','','',1,0,'F','0','0','monitor:operlog:export','#','admin','2024-08-14 02:48:23','',NULL,''),(1042,'登录查询',501,1,'#','','','',1,0,'F','0','0','monitor:logininfor:query','#','admin','2024-08-14 02:48:23','',NULL,''),(1043,'登录删除',501,2,'#','','','',1,0,'F','0','0','monitor:logininfor:remove','#','admin','2024-08-14 02:48:23','',NULL,''),(1044,'日志导出',501,3,'#','','','',1,0,'F','0','0','monitor:logininfor:export','#','admin','2024-08-14 02:48:23','',NULL,''),(1045,'账户解锁',501,4,'#','','','',1,0,'F','0','0','monitor:logininfor:unlock','#','admin','2024-08-14 02:48:23','',NULL,''),(1046,'在线查询',109,1,'#','','','',1,0,'F','0','0','monitor:online:query','#','admin','2024-08-14 02:48:23','',NULL,''),(1047,'批量强退',109,2,'#','','','',1,0,'F','0','0','monitor:online:batchLogout','#','admin','2024-08-14 02:48:23','',NULL,''),(1048,'单条强退',109,3,'#','','','',1,0,'F','0','0','monitor:online:forceLogout','#','admin','2024-08-14 02:48:23','',NULL,''),(1049,'任务查询',110,1,'#','','','',1,0,'F','0','0','monitor:job:query','#','admin','2024-08-14 02:48:23','',NULL,''),(1050,'任务新增',110,2,'#','','','',1,0,'F','0','0','monitor:job:add','#','admin','2024-08-14 02:48:23','',NULL,''),(1051,'任务修改',110,3,'#','','','',1,0,'F','0','0','monitor:job:edit','#','admin','2024-08-14 02:48:23','',NULL,''),(1052,'任务删除',110,4,'#','','','',1,0,'F','0','0','monitor:job:remove','#','admin','2024-08-14 02:48:23','',NULL,''),(1053,'状态修改',110,5,'#','','','',1,0,'F','0','0','monitor:job:changeStatus','#','admin','2024-08-14 02:48:23','',NULL,''),(1054,'任务导出',110,6,'#','','','',1,0,'F','0','0','monitor:job:export','#','admin','2024-08-14 02:48:23','',NULL,''),(1055,'生成查询',116,1,'#','','','',1,0,'F','0','0','tool:gen:query','#','admin','2024-08-14 02:48:23','',NULL,''),(1056,'生成修改',116,2,'#','','','',1,0,'F','0','0','tool:gen:edit','#','admin','2024-08-14 02:48:23','',NULL,''),(1057,'生成删除',116,3,'#','','','',1,0,'F','0','0','tool:gen:remove','#','admin','2024-08-14 02:48:23','',NULL,''),(1058,'导入代码',116,4,'#','','','',1,0,'F','0','0','tool:gen:import','#','admin','2024-08-14 02:48:23','',NULL,''),(1059,'预览代码',116,5,'#','','','',1,0,'F','0','0','tool:gen:preview','#','admin','2024-08-14 02:48:23','',NULL,''),(1060,'生成代码',116,6,'#','','','',1,0,'F','0','0','tool:gen:code','#','admin','2024-08-14 02:48:23','',NULL,''),(2000,'服务管理',0,4,'nursing',NULL,NULL,'',1,0,'M','0','0','','example','admin','2024-08-14 02:59:12','admin','2024-08-29 06:42:37',''),(2001,'护理项目',2000,1,'project','nursing/project/index',NULL,'',1,0,'C','0','0','nursing:project:list','color','admin','2024-08-14 03:00:15','admin','2025-01-01 14:21:47','护理项目菜单'),(2002,'护理项目查询',2001,1,'#','',NULL,'',1,0,'F','0','0','nursing:project:query','#','admin','2024-08-14 03:00:15','',NULL,''),(2003,'护理项目新增',2001,2,'#','',NULL,'',1,0,'F','0','0','nursing:project:add','#','admin','2024-08-14 03:00:15','',NULL,''),(2004,'护理项目修改',2001,3,'#','',NULL,'',1,0,'F','0','0','nursing:project:edit','#','admin','2024-08-14 03:00:15','',NULL,''),(2005,'护理项目删除',2001,4,'#','',NULL,'',1,0,'F','0','0','nursing:project:remove','#','admin','2024-08-14 03:00:15','',NULL,''),(2006,'护理项目导出',2001,5,'#','',NULL,'',1,0,'F','0','0','nursing:project:export','#','admin','2024-08-14 03:00:15','',NULL,''),(2007,'护理等级',2000,3,'level','nursing/level/index',NULL,'',1,0,'C','0','0','nursing:level:list','guide','admin','2024-08-14 08:29:05','admin','2025-01-01 14:22:41','护理等级菜单'),(2008,'护理等级查询',2007,1,'#','',NULL,'',1,0,'F','0','0','nursing:level:query','#','admin','2024-08-14 08:29:05','admin','2024-10-03 10:47:20',''),(2009,'护理等级新增',2007,2,'#','',NULL,'',1,0,'F','0','0','nursing:level:add','#','admin','2024-08-14 08:29:05','admin','2024-10-03 10:47:27',''),(2010,'护理等级修改',2007,3,'#','',NULL,'',1,0,'F','0','0','nursing:level:edit','#','admin','2024-08-14 08:29:05','admin','2024-10-03 10:47:32',''),(2011,'护理等级删除',2007,4,'#','',NULL,'',1,0,'F','0','0','nursing:level:remove','#','admin','2024-08-14 08:29:05','admin','2024-10-03 10:47:37',''),(2012,'护理等级导出',2007,5,'#','',NULL,'',1,0,'F','0','0','nursing:level:export','#','admin','2024-08-14 08:29:05','admin','2024-10-03 10:47:42',''),(2013,'护理计划',2000,2,'plan','nursing/plan/index',NULL,'',1,0,'C','0','0','nursing:plan:list','druid','admin','2024-08-14 08:29:10','admin','2025-01-01 14:22:45','护理计划菜单'),(2014,'护理计划查询',2013,1,'#','',NULL,'',1,0,'F','0','0','nursing:plan:query','#','admin','2024-08-14 08:29:10','',NULL,''),(2015,'护理计划新增',2013,2,'#','',NULL,'',1,0,'F','0','0','nursing:plan:add','#','admin','2024-08-14 08:29:10','',NULL,''),(2016,'护理计划修改',2013,3,'#','',NULL,'',1,0,'F','0','0','nursing:plan:edit','#','admin','2024-08-14 08:29:10','',NULL,''),(2017,'护理计划删除',2013,4,'#','',NULL,'',1,0,'F','0','0','nursing:plan:remove','#','admin','2024-08-14 08:29:10','',NULL,''),(2018,'护理计划导出',2013,5,'#','',NULL,'',1,0,'F','0','0','nursing:plan:export','#','admin','2024-08-14 08:29:10','',NULL,''),(2019,'在住管理',0,3,'liveIn',NULL,NULL,'',1,0,'M','0','0','','date-range','admin','2024-08-22 06:49:19','admin','2024-08-29 06:42:27',''),(2020,'房型设置',2019,0,'houseSet','nursing/roomType/index',NULL,'',1,0,'C','0','0',NULL,'size','admin','2024-08-22 06:50:50','',NULL,''),(2021,'床位预览',2019,2,'floor','nursing/floor/index',NULL,'',1,0,'C','0','0',NULL,'tree-table','admin','2024-08-22 08:15:05','',NULL,''),(2022,'入退管理',0,2,'enterQuit',NULL,NULL,'',1,0,'M','0','0','','component','admin','2024-08-23 12:52:34','admin','2024-08-29 06:42:15',''),(2023,'入住办理',2022,2,'checkIn','nursing/checkIn/index',NULL,'',1,0,'C','0','0','nursing:checkIn:list','edit','admin','2024-08-23 13:13:48','admin','2024-11-07 03:10:32','入住菜单'),(2024,'入住查询',2023,1,'#','',NULL,'',1,0,'F','0','0','nursing:checkIn:query','#','admin','2024-08-23 13:13:48','',NULL,''),(2025,'入住新增',2023,2,'#','',NULL,'',1,0,'F','0','0','nursing:checkIn:add','#','admin','2024-08-23 13:13:48','',NULL,''),(2026,'入住修改',2023,3,'#','',NULL,'',1,0,'F','0','0','nursing:checkIn:edit','#','admin','2024-08-23 13:13:48','',NULL,''),(2027,'入住删除',2023,4,'#','',NULL,'',1,0,'F','0','0','nursing:checkIn:remove','#','admin','2024-08-23 13:13:48','',NULL,''),(2028,'入住导出',2023,5,'#','',NULL,'',1,0,'F','0','0','nursing:checkIn:export','#','admin','2024-08-23 13:13:48','',NULL,''),(2035,'入住详情',2022,0,'checkInInfo','nursing/checkIn/details',NULL,'',1,0,'C','1','0',NULL,'checkbox','admin','2024-08-24 03:44:48','',NULL,''),(2036,'来访管理',0,1,'appointment',NULL,NULL,'',1,0,'M','0','0',NULL,'button','admin','2024-08-29 06:41:45','',NULL,''),(2037,'智能监测',0,5,'intelligence',NULL,NULL,'',1,0,'M','0','0',NULL,'exit-fullscreen','admin','2024-08-29 06:43:14','',NULL,''),(2038,'预约信息',2036,1,'reservation','nursing/reservation/index',NULL,'',1,0,'C','0','0',NULL,'dashboard','admin','2024-08-29 06:47:29','',NULL,''),(2039,'健康评估',2022,1,'healthAssessment','nursing/healthAssessment/index',NULL,'',1,0,'C','0','0',NULL,'eye','admin','2024-08-29 06:48:51','',NULL,''),(2040,'评估详情',2022,2,'healthDetails','nursing/healthAssessment/details',NULL,'',1,0,'C','1','0','','#','admin','2024-08-29 06:49:53','admin','2024-08-29 06:50:06',''),(2041,'负责老人',2000,4,'oldPeople','nursing/oldPeople/index',NULL,'',1,0,'C','0','0','','peoples','admin','2024-08-29 06:52:12','admin','2025-01-01 14:22:01',''),(2042,'任务安排',2000,5,'arrange','nursing/arrange/index',NULL,'',1,0,'C','0','0','','redis-list','admin','2024-08-29 06:53:06','admin','2025-01-01 14:22:04',''),(2043,'任务安排详情',2000,1,'arrangeDetails','nursing/arrange/details',NULL,'',1,0,'C','1','0','','#','admin','2024-08-29 06:53:37','admin','2024-11-03 14:24:57',''),(2044,'设备管理',2037,0,'device','nursing/device/index',NULL,'',1,0,'C','0','0','','tool','admin','2024-08-29 06:54:54','admin','2024-08-29 07:13:42',''),(2045,'设备详情',2037,0,'details','nursing/device/details',NULL,'',1,0,'C','1','0',NULL,'#','admin','2024-08-29 06:55:25','',NULL,''),(2046,'新增报警规则',2037,0,'ruleDetails','nursing/alertRule/details',NULL,'',1,0,'C','1','0',NULL,'#','admin','2024-08-29 06:56:01','',NULL,''),(2047,'报警规则',2037,1,'alertRule','nursing/alertRule/index',NULL,'',1,0,'C','0','0',NULL,'nested','admin','2024-08-29 06:56:48','',NULL,''),(2048,'报警数据',2037,2,'alertData','nursing/alertData/index',NULL,'',1,0,'C','0','0',NULL,'skill','admin','2024-08-29 06:57:25','',NULL,''),(2049,'测试菜单',0,10,'test',NULL,NULL,'',1,0,'M','0','0',NULL,'message','admin','2024-11-09 01:19:22','',NULL,''),(2050,'父子组件',2049,1,'parent','test/parent',NULL,'',1,0,'C','0','0',NULL,'people','admin','2024-11-09 01:20:42','',NULL,''),(2051,'表单构建',2049,2,'check','test/index',NULL,'',1,0,'C','0','0',NULL,'icon','admin','2024-11-09 02:43:49','',NULL,''),(2052,'智能床位',2019,3,'smartBed','nursing/smartBed/index',NULL,'',1,0,'C','0','0',NULL,'online','admin','2024-11-15 02:14:10','',NULL,''); +/*!40000 ALTER TABLE `sys_menu` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `sys_notice` +-- + +DROP TABLE IF EXISTS `sys_notice`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `sys_notice` ( + `notice_id` int NOT NULL AUTO_INCREMENT COMMENT '公告ID', + `notice_title` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '公告标题', + `notice_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '公告类型(1通知 2公告)', + `notice_content` longblob COMMENT '公告内容', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '公告状态(0正常 1关闭)', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '创建者', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '更新者', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`notice_id`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='通知公告表'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `sys_notice` +-- + +LOCK TABLES `sys_notice` WRITE; +/*!40000 ALTER TABLE `sys_notice` DISABLE KEYS */; +INSERT INTO `sys_notice` VALUES (1,'温馨提醒:2018-07-01 若依新版本发布啦','2',_binary '新版本内容','0','admin','2024-08-14 02:48:24','',NULL,'管理员'),(2,'维护通知:2018-07-01 若依系统凌晨维护','1',_binary '维护内容','0','admin','2024-08-14 02:48:24','',NULL,'管理员'); +/*!40000 ALTER TABLE `sys_notice` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `sys_oper_log` +-- + +DROP TABLE IF EXISTS `sys_oper_log`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `sys_oper_log` ( + `oper_id` bigint NOT NULL AUTO_INCREMENT COMMENT '日志主键', + `title` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '模块标题', + `business_type` int DEFAULT '0' COMMENT '业务类型(0其它 1新增 2修改 3删除)', + `method` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '方法名称', + `request_method` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '请求方式', + `operator_type` int DEFAULT '0' COMMENT '操作类别(0其它 1后台用户 2手机端用户)', + `oper_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '操作人员', + `dept_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '部门名称', + `oper_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '请求URL', + `oper_ip` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '主机地址', + `oper_location` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '操作地点', + `oper_param` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '请求参数', + `json_result` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '返回参数', + `status` int DEFAULT '0' COMMENT '操作状态(0正常 1异常)', + `error_msg` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '错误消息', + `oper_time` datetime DEFAULT NULL COMMENT '操作时间', + `cost_time` bigint DEFAULT '0' COMMENT '消耗时间', + PRIMARY KEY (`oper_id`) USING BTREE, + KEY `idx_sys_oper_log_bt` (`business_type`) USING BTREE, + KEY `idx_sys_oper_log_s` (`status`) USING BTREE, + KEY `idx_sys_oper_log_ot` (`oper_time`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=402 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='操作日志记录'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `sys_oper_log` +-- + +LOCK TABLES `sys_oper_log` WRITE; +/*!40000 ALTER TABLE `sys_oper_log` DISABLE KEYS */; +INSERT INTO `sys_oper_log` VALUES (100,'代码生成',6,'com.ruoyi.generator.controller.GenController.importTableSave()','POST',1,'admin','研发部门','/tool/gen/importTable','127.0.0.1','内网IP','{\"tables\":\"nursing_project\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-14 02:56:15',107),(101,'代码生成',2,'com.ruoyi.generator.controller.GenController.editSave()','PUT',1,'admin','研发部门','/tool/gen','127.0.0.1','内网IP','{\"businessName\":\"project\",\"className\":\"NursingProject\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"编号\",\"columnId\":1,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 02:56:15\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":false,\"isIncrement\":\"1\",\"isInsert\":\"0\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":1,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"Name\",\"columnComment\":\"名称\",\"columnId\":2,\"columnName\":\"name\",\"columnType\":\"varchar(100)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 02:56:15\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"name\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":false,\"sort\":2,\"superColumn\":false,\"tableId\":1,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"OrderNo\",\"columnComment\":\"排序号\",\"columnId\":3,\"columnName\":\"order_no\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 02:56:15\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"0\",\"isRequired\":\"0\",\"javaField\":\"orderNo\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":3,\"superColumn\":false,\"tableId\":1,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"Unit\",\"columnComment\":\"单位\",\"columnId\":4,\"columnName\":\"unit\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 02:56:15\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"0\",\"isRequired\":\"0\",\"javaField\":\"unit\",\"javaType\":\"String\",\"li','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-14 02:57:47',67),(102,'菜单管理',1,'com.ruoyi.web.controller.system.SysMenuController.add()','POST',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"createBy\":\"admin\",\"icon\":\"example\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuName\":\"服务管理\",\"menuType\":\"M\",\"orderNum\":1,\"params\":{},\"parentId\":0,\"path\":\"serve\",\"status\":\"0\",\"visible\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-14 02:59:12',25),(103,'代码生成',2,'com.ruoyi.generator.controller.GenController.editSave()','PUT',1,'admin','研发部门','/tool/gen','127.0.0.1','内网IP','{\"businessName\":\"project\",\"className\":\"NursingProject\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"编号\",\"columnId\":1,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 02:56:15\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":false,\"isIncrement\":\"1\",\"isInsert\":\"0\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":1,\"updateBy\":\"\",\"updateTime\":\"2024-08-14 02:57:47\",\"usableColumn\":false},{\"capJavaField\":\"Name\",\"columnComment\":\"名称\",\"columnId\":2,\"columnName\":\"name\",\"columnType\":\"varchar(100)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 02:56:15\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"name\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":false,\"sort\":2,\"superColumn\":false,\"tableId\":1,\"updateBy\":\"\",\"updateTime\":\"2024-08-14 02:57:47\",\"usableColumn\":false},{\"capJavaField\":\"OrderNo\",\"columnComment\":\"排序号\",\"columnId\":3,\"columnName\":\"order_no\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 02:56:15\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"0\",\"isRequired\":\"0\",\"javaField\":\"orderNo\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":3,\"superColumn\":false,\"tableId\":1,\"updateBy\":\"\",\"updateTime\":\"2024-08-14 02:57:47\",\"usableColumn\":false},{\"capJavaField\":\"Unit\",\"columnComment\":\"单位\",\"columnId\":4,\"columnName\":\"unit\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 02:56:15\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInse','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-14 02:59:30',60),(104,'代码生成',8,'com.ruoyi.generator.controller.GenController.batchGenCode()','GET',1,'admin','研发部门','/tool/gen/batchGenCode','127.0.0.1','内网IP','{\"tables\":\"nursing_project\"}','',0,'','2024-08-14 02:59:33',445),(105,'护理项目',1,'com.ruoyi.serve.controller.NursingProjectController.add()','POST',1,'admin','研发部门','/serve/project','127.0.0.1','内网IP','{\"createTime\":\"2024-08-14 11:02:15\",\"id\":84,\"image\":\"/profile/upload/2024/08/14/复建运动@2x_20240814110214A001.png\",\"name\":\"11\",\"nursingRequirement\":\"111\",\"orderNo\":11,\"params\":{},\"price\":1,\"unit\":\"1\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-14 03:02:16',31),(106,'护理项目',2,'com.ruoyi.serve.controller.NursingProjectController.edit()','PUT',1,'admin','研发部门','/serve/project','127.0.0.1','内网IP','{\"createTime\":\"2024-08-14 11:02:16\",\"id\":84,\"image\":\"/profile/upload/2024/08/14/复建运动@2x_20240814110214A001.png\",\"name\":\"222\",\"nursingRequirement\":\"111\",\"orderNo\":2,\"params\":{},\"price\":1,\"status\":1,\"unit\":\"2\",\"updateTime\":\"2024-08-14 11:02:21\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-14 03:02:21',8),(107,'护理项目',3,'com.ruoyi.serve.controller.NursingProjectController.remove()','DELETE',1,'admin','研发部门','/serve/project/84','127.0.0.1','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-14 03:02:24',9),(108,'护理项目',1,'com.ruoyi.serve.controller.NursingProjectController.add()','POST',1,'admin','研发部门','/serve/project','127.0.0.1','内网IP','{\"createTime\":\"2024-08-14 11:39:59\",\"id\":85,\"image\":\"/profile/upload/2024/08/14/助餐@2x_20240814113958A001.png\",\"name\":\"测试护理项目\",\"nursingRequirement\":\"测试护理项目\",\"orderNo\":1,\"params\":{},\"price\":50,\"unit\":\"元\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-14 03:40:00',42),(109,'代码生成',6,'com.ruoyi.generator.controller.GenController.importTableSave()','POST',1,'admin','研发部门','/tool/gen/importTable','127.0.0.1','内网IP','{\"tables\":\"nursing_level,nursing_plan,nursing_project_plan\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-14 07:37:36',199),(110,'代码生成',2,'com.zzyl.generator.controller.GenController.editSave()','PUT',1,'admin','研发部门','/tool/gen','127.0.0.1','内网IP','{\"businessName\":\"nursingLevel\",\"className\":\"NursingLevel\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键ID\",\"columnId\":14,\"columnName\":\"id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 07:37:35\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":false,\"isIncrement\":\"1\",\"isInsert\":\"0\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"Name\",\"columnComment\":\"等级名称\",\"columnId\":15,\"columnName\":\"name\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 07:37:35\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"name\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"LplanId\",\"columnComment\":\"护理计划ID\",\"columnId\":16,\"columnName\":\"lplan_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 07:37:35\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"0\",\"isRequired\":\"0\",\"javaField\":\"lplanId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":3,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"Fee\",\"columnComment\":\"护理费用\",\"columnId\":17,\"columnName\":\"fee\",\"columnType\":\"decimal(10,2)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 07:37:35\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"0\",\"isRequired\":\"0\",\"javaField\":\"fee\",\"javaType\":\"B','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-14 08:27:28',108),(111,'代码生成',2,'com.zzyl.generator.controller.GenController.editSave()','PUT',1,'admin','研发部门','/tool/gen','127.0.0.1','内网IP','{\"businessName\":\"nursingPlan\",\"className\":\"NursingPlan\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"编号\",\"columnId\":25,\"columnName\":\"id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 07:37:36\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":false,\"isIncrement\":\"1\",\"isInsert\":\"0\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":3,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"SortNo\",\"columnComment\":\"排序号\",\"columnId\":26,\"columnName\":\"sort_no\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 07:37:36\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"0\",\"isRequired\":\"0\",\"javaField\":\"sortNo\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":2,\"superColumn\":false,\"tableId\":3,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"PlanName\",\"columnComment\":\"名称\",\"columnId\":27,\"columnName\":\"plan_name\",\"columnType\":\"varchar(255)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 07:37:36\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"planName\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":3,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"Status\",\"columnComment\":\"状态 0禁用 1启用\",\"columnId\":28,\"columnName\":\"status\",\"columnType\":\"tinyint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 07:37:36\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"radio\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"status\",\"j','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-14 08:28:14',45),(112,'代码生成',8,'com.zzyl.generator.controller.GenController.batchGenCode()','GET',1,'admin','研发部门','/tool/gen/batchGenCode','127.0.0.1','内网IP','{\"tables\":\"nursing_level,nursing_plan\"}','',0,'','2024-08-14 08:28:26',349),(113,'护理等级',1,'com.zzyl.nursing.controller.NursingLevelController.add()','POST',1,'admin','研发部门','/nursing/nursingLevel','127.0.0.1','内网IP','{\"createTime\":\"2024-08-14 16:33:15\",\"description\":\"1223\",\"fee\":100,\"id\":76,\"lplanId\":1,\"name\":\"测试护理等级\",\"params\":{}}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-14 08:33:16',17),(114,'护理计划',1,'com.zzyl.nursing.controller.NursingPlanController.add()','POST',1,'admin','研发部门','/nursing/nursingPlan','127.0.0.1','内网IP','{\"createTime\":\"2024-08-14 16:33:35\",\"id\":129,\"params\":{},\"planName\":\"测试护理等级\",\"sortNo\":1}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-14 08:33:36',8),(115,'护理项目',1,'com.zzyl.nursing.controller.NursingProjectController.add()','POST',1,'admin','研发部门','/serve/project','127.0.0.1','内网IP','{\"createTime\":\"2024-08-18 09:57:59\",\"id\":86,\"image\":\"/profile/upload/2024/08/18/助浴@2x_20240818095758A001.png\",\"name\":\"22\",\"nursingRequirement\":\"22\",\"orderNo\":2,\"params\":{},\"price\":2,\"unit\":\"2\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-18 01:57:59',20),(116,'护理项目',2,'com.zzyl.nursing.controller.NursingProjectController.edit()','PUT',1,'admin','研发部门','/serve/project','127.0.0.1','内网IP','{\"id\":85,\"params\":{},\"status\":1,\"updateTime\":\"2024-08-18 10:14:02\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-18 02:14:03',5),(117,'护理项目',2,'com.zzyl.nursing.controller.NursingProjectController.edit()','PUT',1,'admin','研发部门','/serve/project','127.0.0.1','内网IP','{\"id\":85,\"params\":{},\"status\":0,\"updateTime\":\"2024-08-18 10:14:05\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-18 02:14:05',4),(118,'护理项目',2,'com.zzyl.nursing.controller.NursingProjectController.edit()','PUT',1,'admin','研发部门','/serve/project','127.0.0.1','内网IP','{\"id\":86,\"params\":{},\"status\":0,\"updateTime\":\"2024-08-18 10:14:08\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-18 02:14:08',3),(119,'护理项目',2,'com.zzyl.nursing.controller.NursingProjectController.edit()','PUT',1,'admin','研发部门','/serve/project','127.0.0.1','内网IP','{\"id\":86,\"params\":{},\"status\":1,\"updateTime\":\"2024-08-18 10:14:10\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-18 02:14:10',5),(120,'字典类型',1,'com.zzyl.web.controller.system.SysDictTypeController.add()','POST',1,'admin','研发部门','/system/dict/type','127.0.0.1','内网IP','{\"createBy\":\"admin\",\"dictName\":\"护理项目状态\",\"dictType\":\"nursing_project_status\",\"params\":{},\"status\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-18 02:40:48',11),(121,'字典数据',1,'com.zzyl.web.controller.system.SysDictDataController.add()','POST',1,'admin','研发部门','/system/dict/data','127.0.0.1','内网IP','{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"启用\",\"dictSort\":0,\"dictType\":\"nursing_project_status\",\"dictValue\":\"1\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-18 02:41:15',12),(122,'字典数据',1,'com.zzyl.web.controller.system.SysDictDataController.add()','POST',1,'admin','研发部门','/system/dict/data','127.0.0.1','内网IP','{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"禁用\",\"dictSort\":0,\"dictType\":\"nursing_project_status\",\"dictValue\":\"0\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-18 02:41:30',11),(123,'字典数据',1,'com.zzyl.web.controller.system.SysDictDataController.add()','POST',1,'admin','研发部门','/system/dict/data','127.0.0.1','内网IP','{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"其他\",\"dictSort\":0,\"dictType\":\"nursing_project_status\",\"dictValue\":\"2\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-18 02:43:19',9),(124,'字典类型',3,'com.zzyl.web.controller.system.SysDictDataController.remove()','DELETE',1,'admin','研发部门','/system/dict/data/102','127.0.0.1','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-18 02:43:47',17),(125,'护理项目',1,'com.zzyl.nursing.controller.NursingProjectController.add()','POST',1,'admin','研发部门','/serve/project','127.0.0.1','内网IP','{\"createTime\":\"2024-08-18 10:58:31\",\"id\":87,\"image\":\"/profile/upload/2024/08/18/助餐@2x_20240818105812A002.png\",\"name\":\"喂饭\",\"nursingRequirement\":\"无\",\"orderNo\":1,\"params\":{},\"price\":6,\"status\":1,\"unit\":\"元\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-18 02:58:31',7),(126,'护理计划',2,'com.zzyl.nursing.controller.NursingPlanController.edit()','PUT',1,'admin','研发部门','/nursing/nursingPlan','127.0.0.1','内网IP','{\"id\":129,\"params\":{},\"status\":1,\"updateTime\":\"2024-08-19 10:47:23\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-19 02:47:23',23),(127,'护理计划',2,'com.zzyl.nursing.controller.NursingPlanController.edit()','PUT',1,'admin','研发部门','/nursing/nursingPlan','127.0.0.1','内网IP','{\"id\":129,\"params\":{},\"status\":1,\"updateTime\":\"2024-08-19 10:47:42\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-19 02:47:42',5),(128,'护理计划',2,'com.zzyl.nursing.controller.NursingPlanController.edit()','PUT',1,'admin','研发部门','/nursing/nursingPlan','127.0.0.1','内网IP','{\"id\":129,\"params\":{},\"status\":0,\"updateTime\":\"2024-08-19 10:49:01\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-19 02:49:01',13),(129,'护理计划',2,'com.zzyl.nursing.controller.NursingPlanController.edit()','PUT',1,'admin','研发部门','/nursing/nursingPlan','127.0.0.1','内网IP','{\"id\":129,\"params\":{},\"status\":1,\"updateTime\":\"2024-08-19 10:52:03\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-19 02:52:03',6),(130,'护理计划',2,'com.zzyl.nursing.controller.NursingPlanController.edit()','PUT',1,'admin','研发部门','/nursing/nursingPlan','127.0.0.1','内网IP','{\"id\":129,\"params\":{},\"status\":0,\"updateTime\":\"2024-08-19 10:52:05\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-19 02:52:05',5),(131,'护理计划',1,'com.zzyl.nursing.controller.NursingPlanController.add()','POST',1,'admin','研发部门','/nursing/nursingPlan','127.0.0.1','内网IP','{\"createTime\":\"2024-08-19 10:53:03\",\"id\":130,\"params\":{},\"planName\":\"6号护理计划\",\"sortNo\":1,\"status\":1}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-19 02:53:03',6),(132,'护理计划',2,'com.zzyl.nursing.controller.NursingPlanController.edit()','PUT',1,'admin','研发部门','/nursing/nursingPlan','127.0.0.1','内网IP','{\"id\":130,\"params\":{},\"status\":0,\"updateTime\":\"2024-08-19 10:53:13\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-19 02:53:13',4),(133,'护理计划',2,'com.zzyl.nursing.controller.NursingPlanController.edit()','PUT',1,'admin','研发部门','/nursing/nursingPlan','127.0.0.1','内网IP','{\"id\":130,\"params\":{},\"status\":1,\"updateTime\":\"2024-08-19 10:53:15\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-19 02:53:15',4),(134,'护理计划',2,'com.zzyl.nursing.controller.NursingPlanController.edit()','PUT',1,'admin','研发部门','/nursing/plan','127.0.0.1','内网IP','{\"id\":129,\"params\":{},\"status\":1,\"updateTime\":\"2024-08-19 16:47:04\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-19 08:47:04',11),(135,'护理计划',2,'com.zzyl.nursing.controller.NursingPlanController.edit()','PUT',1,'admin','研发部门','/nursing/plan','127.0.0.1','内网IP','{\"id\":129,\"params\":{},\"status\":0,\"updateTime\":\"2024-08-19 16:47:06\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-19 08:47:06',4),(136,'护理计划',1,'com.zzyl.nursing.controller.NursingPlanController.add()','POST',1,'admin','研发部门','/nursing/plan','127.0.0.1','内网IP','{\"planName\":\"测试护理计划1\",\"projectPlans\":[{\"executeCycle\":0,\"executeFrequency\":1,\"executeTime\":\"17:11:40\",\"params\":{},\"projectId\":86},{\"executeCycle\":1,\"executeFrequency\":1,\"executeTime\":\"17:11:52\",\"params\":{},\"projectId\":87}],\"sortNo\":1,\"status\":1}','',1,'\r\n### Error updating database. Cause: java.sql.SQLException: Field \'create_time\' doesn\'t have a default value\r\n### The error may exist in file [E:\\code\\2024\\zzyl-ruoyi-ai-code\\day02\\zzyl\\zzyl-nursing-platform\\target\\classes\\mapper\\nursing\\NursingPlanMapper.xml]\r\n### The error may involve com.zzyl.nursing.mapper.NursingPlanMapper.insertNursingPlan-Inline\r\n### The error occurred while setting parameters\r\n### SQL: insert into nursing_plan ( sort_no, plan_name, status ) values ( ?, ?, ? )\r\n### Cause: java.sql.SQLException: Field \'create_time\' doesn\'t have a default value\n; Field \'create_time\' doesn\'t have a default value; nested exception is java.sql.SQLException: Field \'create_time\' doesn\'t have a default value','2024-08-19 09:11:58',57),(137,'护理计划',1,'com.zzyl.nursing.controller.NursingPlanController.add()','POST',1,'admin','研发部门','/nursing/plan','127.0.0.1','内网IP','{\"planName\":\"测试护理计划1\",\"projectPlans\":[{\"executeCycle\":0,\"executeFrequency\":1,\"executeTime\":\"17:11:40\",\"params\":{},\"projectId\":86},{\"executeCycle\":1,\"executeFrequency\":1,\"executeTime\":\"17:11:52\",\"params\":{},\"projectId\":87}],\"sortNo\":1,\"status\":1}','',1,'\r\n### Error updating database. Cause: java.sql.SQLException: Field \'create_time\' doesn\'t have a default value\r\n### The error may exist in file [E:\\code\\2024\\zzyl-ruoyi-ai-code\\day02\\zzyl\\zzyl-nursing-platform\\target\\classes\\mapper\\nursing\\NursingPlanMapper.xml]\r\n### The error may involve com.zzyl.nursing.mapper.NursingPlanMapper.insertNursingPlan-Inline\r\n### The error occurred while setting parameters\r\n### SQL: insert into nursing_plan ( sort_no, plan_name, status ) values ( ?, ?, ? )\r\n### Cause: java.sql.SQLException: Field \'create_time\' doesn\'t have a default value\n; Field \'create_time\' doesn\'t have a default value; nested exception is java.sql.SQLException: Field \'create_time\' doesn\'t have a default value','2024-08-19 09:12:07',7),(138,'护理计划',1,'com.zzyl.nursing.controller.NursingPlanController.add()','POST',1,'admin','研发部门','/nursing/plan','127.0.0.1','内网IP','{\"planName\":\"测试护理计划1\",\"projectPlans\":[{\"executeCycle\":0,\"executeFrequency\":1,\"executeTime\":\"17:11:40\",\"params\":{},\"projectId\":86},{\"executeCycle\":1,\"executeFrequency\":1,\"executeTime\":\"17:11:52\",\"params\":{},\"projectId\":87}],\"sortNo\":1,\"status\":1}','',1,'\r\n### Error updating database. Cause: java.sql.SQLIntegrityConstraintViolationException: Column \'create_time\' cannot be null\r\n### The error may exist in file [E:\\code\\2024\\zzyl-ruoyi-ai-code\\day02\\zzyl\\zzyl-nursing-platform\\target\\classes\\mapper\\nursing\\NursingProjectPlanMapper.xml]\r\n### The error may involve defaultParameterMap\r\n### The error occurred while setting parameters\r\n### SQL: INSERT INTO nursing_project_plan (plan_id, project_id, execute_time, execute_cycle, execute_frequency, create_by, update_by, create_time, update_time) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) , (?, ?, ?, ?, ?, ?, ?, ?, ?)\r\n### Cause: java.sql.SQLIntegrityConstraintViolationException: Column \'create_time\' cannot be null\n; Column \'create_time\' cannot be null; nested exception is java.sql.SQLIntegrityConstraintViolationException: Column \'create_time\' cannot be null','2024-08-19 09:13:23',303),(139,'护理计划',1,'com.zzyl.nursing.controller.NursingPlanController.add()','POST',1,'admin','研发部门','/nursing/plan','127.0.0.1','内网IP','{\"planName\":\"测试护理计划1\",\"projectPlans\":[{\"executeCycle\":0,\"executeFrequency\":1,\"executeTime\":\"17:11:40\",\"params\":{},\"projectId\":86},{\"executeCycle\":1,\"executeFrequency\":1,\"executeTime\":\"17:11:52\",\"params\":{},\"projectId\":87}],\"sortNo\":1,\"status\":1}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-19 09:15:13',215),(140,'护理计划',3,'com.zzyl.nursing.controller.NursingPlanController.remove()','DELETE',1,'admin','研发部门','/nursing/plan/129','127.0.0.1','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-19 10:58:35',16),(141,'护理计划',2,'com.zzyl.nursing.controller.NursingPlanController.edit()','PUT',1,'admin','研发部门','/nursing/plan','127.0.0.1','内网IP','{\"id\":130,\"params\":{},\"status\":0,\"updateTime\":\"2024-08-19 18:58:46\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-19 10:58:46',15),(142,'护理计划',2,'com.zzyl.nursing.controller.NursingPlanController.edit()','PUT',1,'admin','研发部门','/nursing/plan','127.0.0.1','内网IP','{\"id\":130,\"params\":{},\"status\":1,\"updateTime\":\"2024-08-19 18:58:48\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-19 10:58:48',7),(143,'字典类型',1,'com.zzyl.web.controller.system.SysDictTypeController.add()','POST',1,'admin','研发部门','/system/dict/type','127.0.0.1','内网IP','{\"createBy\":\"admin\",\"dictName\":\"护理计划状态\",\"dictType\":\"nursing_plan_status\",\"params\":{},\"status\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-19 10:59:40',16),(144,'字典数据',1,'com.zzyl.web.controller.system.SysDictDataController.add()','POST',1,'admin','研发部门','/system/dict/data','127.0.0.1','内网IP','{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"启用\",\"dictSort\":0,\"dictType\":\"nursing_plan_status\",\"dictValue\":\"1\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-19 11:00:04',15),(145,'字典数据',1,'com.zzyl.web.controller.system.SysDictDataController.add()','POST',1,'admin','研发部门','/system/dict/data','127.0.0.1','内网IP','{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"禁用\",\"dictSort\":0,\"dictType\":\"nursing_plan_status\",\"dictValue\":\"2\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-19 11:00:10',15),(146,'护理计划',2,'com.zzyl.nursing.controller.NursingPlanController.edit()','PUT',1,'admin','研发部门','/nursing/plan','127.0.0.1','内网IP','{\"id\":132,\"planName\":\"测试护理计划1\",\"projectPlans\":[{\"createTime\":\"2024-08-19 09:15:13\",\"executeCycle\":1,\"executeFrequency\":1,\"executeTime\":\"17:11:52\",\"id\":1728,\"params\":{},\"planId\":132,\"projectId\":87}],\"sortNo\":1,\"status\":1}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-19 11:12:59',36),(147,'护理计划',2,'com.zzyl.nursing.controller.NursingPlanController.edit()','PUT',1,'admin','研发部门','/nursing/plan','127.0.0.1','内网IP','{\"id\":132,\"planName\":\"测试护理计划1\",\"projectPlans\":[{\"createTime\":\"2024-08-19 09:15:13\",\"executeCycle\":1,\"executeFrequency\":1,\"executeTime\":\"17:11:52\",\"id\":1728,\"params\":{},\"planId\":132,\"projectId\":87}],\"sortNo\":1,\"status\":1}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-19 11:13:15',11),(148,'护理计划',2,'com.zzyl.nursing.controller.NursingPlanController.edit()','PUT',1,'admin','研发部门','/nursing/plan','127.0.0.1','内网IP','{\"id\":132,\"planName\":\"测试护理计划1\",\"projectPlans\":[{\"createTime\":\"2024-08-19 11:13:15\",\"executeCycle\":1,\"executeFrequency\":1,\"executeTime\":\"17:11:52\",\"id\":1730,\"params\":{},\"planId\":132,\"projectId\":87}],\"sortNo\":1,\"status\":1}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-19 11:14:48',71979),(149,'护理计划',2,'com.zzyl.nursing.controller.NursingPlanController.edit()','PUT',1,'admin','研发部门','/nursing/plan','127.0.0.1','内网IP','{\"id\":132,\"planName\":\"测试护理计划1\",\"projectPlans\":[{\"createTime\":\"2024-08-19 09:15:13\",\"executeCycle\":0,\"executeFrequency\":1,\"executeTime\":\"17:11:40\",\"id\":1727,\"params\":{},\"planId\":132,\"projectId\":86},{\"createTime\":\"2024-08-19 11:14:48\",\"executeCycle\":1,\"executeFrequency\":1,\"executeTime\":\"17:11:52\",\"id\":1731,\"params\":{},\"planId\":132,\"projectId\":87}],\"sortNo\":1,\"status\":1}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-19 11:16:40',5657),(150,'护理计划',2,'com.zzyl.nursing.controller.NursingPlanController.edit()','PUT',1,'admin','研发部门','/nursing/plan','127.0.0.1','内网IP','{\"id\":132,\"planName\":\"测试护理计划1\",\"projectPlans\":[{\"createTime\":\"2024-08-19 11:16:40\",\"executeCycle\":1,\"executeFrequency\":1,\"executeTime\":\"17:11:52\",\"id\":1733,\"params\":{},\"planId\":132,\"projectId\":87}],\"sortNo\":1,\"status\":1}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-19 11:16:46',32),(151,'护理计划',3,'com.zzyl.nursing.controller.NursingPlanController.remove()','DELETE',1,'admin','研发部门','/nursing/plan/130','127.0.0.1','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-19 11:16:58',8),(152,'护理计划',3,'com.zzyl.nursing.controller.NursingPlanController.remove()','DELETE',1,'admin','研发部门','/nursing/plan/132','127.0.0.1','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-19 11:17:05',10),(153,'护理计划',1,'com.zzyl.nursing.controller.NursingPlanController.add()','POST',1,'admin','研发部门','/nursing/plan','127.0.0.1','内网IP','{\"planName\":\"1号护理计划\",\"projectPlans\":[{\"executeCycle\":1,\"executeFrequency\":7,\"executeTime\":\"19:16:49\",\"params\":{},\"projectId\":87}],\"sortNo\":1,\"status\":1}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-19 11:17:31',20),(154,'护理计划',2,'com.zzyl.nursing.controller.NursingPlanController.edit()','PUT',1,'admin','研发部门','/nursing/plan','127.0.0.1','内网IP','{\"id\":133,\"status\":0}','',1,'nested exception is org.apache.ibatis.builder.BuilderException: The expression \'list\' evaluated to a null value.','2024-08-19 11:17:37',8),(155,'护理计划',2,'com.zzyl.nursing.controller.NursingPlanController.edit()','PUT',1,'admin','研发部门','/nursing/plan','127.0.0.1','内网IP','{\"id\":133,\"status\":0}','',1,'nested exception is org.apache.ibatis.builder.BuilderException: The expression \'list\' evaluated to a null value.','2024-08-19 11:17:45',5),(156,'护理计划',2,'com.zzyl.nursing.controller.NursingPlanController.edit()','PUT',1,'admin','研发部门','/nursing/plan','127.0.0.1','内网IP','{\"id\":133,\"status\":0}','',1,'nested exception is org.apache.ibatis.builder.BuilderException: The expression \'list\' evaluated to a null value.','2024-08-19 11:17:55',7),(157,'护理计划',2,'com.zzyl.nursing.controller.NursingPlanController.edit()','PUT',1,'admin','研发部门','/nursing/plan','127.0.0.1','内网IP','{\"id\":133,\"status\":0}','',1,'','2024-08-19 11:27:23',15),(158,'护理计划',2,'com.zzyl.nursing.controller.NursingPlanController.edit()','PUT',1,'admin','研发部门','/nursing/plan','127.0.0.1','内网IP','{\"id\":133,\"status\":0}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-19 11:28:24',2392),(159,'护理计划',2,'com.zzyl.nursing.controller.NursingPlanController.edit()','PUT',1,'admin','研发部门','/nursing/plan','127.0.0.1','内网IP','{\"id\":133,\"status\":1}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-19 11:28:28',12),(160,'护理计划',2,'com.zzyl.nursing.controller.NursingPlanController.edit()','PUT',1,'admin','研发部门','/nursing/plan','127.0.0.1','内网IP','{\"id\":133,\"status\":0}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-19 11:28:30',16),(161,'护理计划',2,'com.zzyl.nursing.controller.NursingPlanController.edit()','PUT',1,'admin','研发部门','/nursing/plan','127.0.0.1','内网IP','{\"id\":133,\"status\":1}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-19 11:28:32',10),(162,'护理计划',2,'com.zzyl.nursing.controller.NursingPlanController.edit()','PUT',1,'admin','研发部门','/nursing/plan','127.0.0.1','内网IP','{\"id\":133,\"planName\":\"1号护理计划\",\"projectPlans\":[{\"createTime\":\"2024-08-19 11:17:31\",\"executeCycle\":1,\"executeFrequency\":7,\"executeTime\":\"19:16:49\",\"id\":1735,\"params\":{},\"planId\":133,\"projectId\":87},{\"executeCycle\":1,\"executeFrequency\":1,\"executeTime\":\"19:28:34\",\"params\":{},\"projectId\":85}],\"sortNo\":1,\"status\":1}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-19 11:28:43',19),(163,'护理计划',1,'com.zzyl.nursing.controller.NursingPlanController.add()','POST',1,'admin','研发部门','/nursing/plan','127.0.0.1','内网IP','{\"planName\":\"2号护理计划\",\"projectPlans\":[{\"executeCycle\":0,\"executeFrequency\":1,\"executeTime\":\"19:28:45\",\"params\":{},\"projectId\":85}],\"sortNo\":1,\"status\":1}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-19 11:36:10',34),(164,'护理计划',2,'com.zzyl.nursing.controller.NursingPlanController.edit()','PUT',1,'admin','研发部门','/nursing/plan','127.0.0.1','内网IP','{\"id\":134,\"status\":0}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-19 11:36:13',6),(165,'护理项目',2,'com.zzyl.nursing.controller.NursingProjectController.edit()','PUT',1,'admin','研发部门','/serve/project','127.0.0.1','内网IP','{\"createTime\":\"2024-08-18 09:57:59\",\"id\":86,\"image\":\"/profile/upload/2024/08/18/助浴@2x_20240818095758A001.png\",\"name\":\"洗衣服\",\"nursingRequirement\":\"22\",\"orderNo\":2,\"params\":{},\"price\":5,\"status\":1,\"unit\":\"元\",\"updateTime\":\"2024-08-19 20:24:49\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-19 12:24:49',10),(166,'菜单管理',2,'com.zzyl.web.controller.system.SysMenuController.edit()','PUT',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"createTime\":\"2024-08-14 02:48:23\",\"icon\":\"guide\",\"isCache\":\"0\",\"isFrame\":\"0\",\"menuId\":4,\"menuName\":\"若依官网\",\"menuType\":\"M\",\"orderNum\":4,\"params\":{},\"parentId\":0,\"path\":\"http://ruoyi.vip\",\"perms\":\"\",\"query\":\"\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"1\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-20 01:57:10',20),(167,'护理等级',2,'com.zzyl.nursing.controller.NursingLevelController.edit()','PUT',1,'admin','研发部门','/nursing/level','127.0.0.1','内网IP','{\"id\":76,\"params\":{},\"status\":0,\"updateTime\":\"2024-08-20 10:49:50\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-20 02:49:49',10),(168,'护理等级',2,'com.zzyl.nursing.controller.NursingLevelController.edit()','PUT',1,'admin','研发部门','/nursing/level','127.0.0.1','内网IP','{\"id\":76,\"params\":{},\"status\":1,\"updateTime\":\"2024-08-20 10:49:52\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-20 02:49:52',4),(169,'护理等级',2,'com.zzyl.nursing.controller.NursingLevelController.edit()','PUT',1,'admin','研发部门','/nursing/level','127.0.0.1','内网IP','{\"id\":76,\"params\":{},\"status\":0,\"updateTime\":\"2024-08-20 10:55:09\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-20 02:55:09',24),(170,'护理等级',2,'com.zzyl.nursing.controller.NursingLevelController.edit()','PUT',1,'admin','研发部门','/nursing/level','127.0.0.1','内网IP','{\"id\":76,\"params\":{},\"status\":1,\"updateTime\":\"2024-08-20 10:55:11\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-20 02:55:11',4),(171,'护理等级',2,'com.zzyl.nursing.controller.NursingLevelController.edit()','PUT',1,'admin','研发部门','/nursing/level','127.0.0.1','内网IP','{\"id\":76,\"params\":{},\"status\":0,\"updateTime\":\"2024-08-20 10:55:15\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-20 02:55:15',4),(172,'护理等级',2,'com.zzyl.nursing.controller.NursingLevelController.edit()','PUT',1,'admin','研发部门','/nursing/level','127.0.0.1','内网IP','{\"id\":76,\"params\":{},\"status\":1,\"updateTime\":\"2024-08-20 10:55:20\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-20 02:55:20',6),(173,'护理等级',2,'com.zzyl.nursing.controller.NursingLevelController.edit()','PUT',1,'admin','研发部门','/nursing/level','127.0.0.1','内网IP','{\"id\":76,\"params\":{},\"status\":0,\"updateTime\":\"2024-08-20 10:55:23\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-20 02:55:23',4),(174,'护理等级',2,'com.zzyl.nursing.controller.NursingLevelController.edit()','PUT',1,'admin','研发部门','/nursing/level','127.0.0.1','内网IP','{\"id\":76,\"params\":{},\"status\":1,\"updateTime\":\"2024-08-20 11:02:26\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-20 03:02:26',22),(175,'字典类型',1,'com.zzyl.web.controller.system.SysDictTypeController.add()','POST',1,'admin','研发部门','/system/dict/type','127.0.0.1','内网IP','{\"createBy\":\"admin\",\"dictName\":\"护理等级状态\",\"dictType\":\"nursing_level_status\",\"params\":{},\"status\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-20 03:04:03',14),(176,'字典数据',1,'com.zzyl.web.controller.system.SysDictDataController.add()','POST',1,'admin','研发部门','/system/dict/data','127.0.0.1','内网IP','{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"启用\",\"dictSort\":0,\"dictType\":\"nursing_level_status\",\"dictValue\":\"1\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-20 03:04:14',11),(177,'字典数据',1,'com.zzyl.web.controller.system.SysDictDataController.add()','POST',1,'admin','研发部门','/system/dict/data','127.0.0.1','内网IP','{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"禁用\",\"dictSort\":0,\"dictType\":\"nursing_level_status\",\"dictValue\":\"0\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-20 03:04:21',10),(178,'护理等级',1,'com.zzyl.nursing.controller.NursingLevelController.add()','POST',1,'admin','研发部门','/nursing/level','127.0.0.1','内网IP','{\"createTime\":\"2024-08-20 11:18:08\",\"description\":\"1223\",\"lplanId\":133,\"name\":\"1号护理计划\",\"params\":{},\"status\":1}','',1,'\r\n### Error updating database. Cause: java.sql.SQLException: Field \'fee\' doesn\'t have a default value\r\n### The error may exist in file [E:\\code\\2024\\zzyl-ruoyi-ai-code\\day02\\zzyl\\zzyl-nursing-platform\\target\\classes\\mapper\\nursing\\NursingLevelMapper.xml]\r\n### The error may involve com.zzyl.nursing.mapper.NursingLevelMapper.insertNursingLevel-Inline\r\n### The error occurred while setting parameters\r\n### SQL: insert into nursing_level ( name, lplan_id, status, description, create_time ) values ( ?, ?, ?, ?, ? )\r\n### Cause: java.sql.SQLException: Field \'fee\' doesn\'t have a default value\n; Field \'fee\' doesn\'t have a default value; nested exception is java.sql.SQLException: Field \'fee\' doesn\'t have a default value','2024-08-20 03:18:08',58),(179,'护理等级',1,'com.zzyl.nursing.controller.NursingLevelController.add()','POST',1,'admin','研发部门','/nursing/level','127.0.0.1','内网IP','{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000,\"id\":77,\"lplanId\":133,\"name\":\"1号护理计划\",\"params\":{},\"status\":1}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-20 03:18:21',7),(180,'护理等级',2,'com.zzyl.nursing.controller.NursingLevelController.edit()','PUT',1,'admin','研发部门','/nursing/level','127.0.0.1','内网IP','{\"id\":77,\"params\":{},\"status\":0,\"updateTime\":\"2024-08-20 11:18:35\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-20 03:18:35',7),(181,'护理等级',2,'com.zzyl.nursing.controller.NursingLevelController.edit()','PUT',1,'admin','研发部门','/nursing/level','127.0.0.1','内网IP','{\"id\":77,\"params\":{},\"status\":1,\"updateTime\":\"2024-08-20 11:18:37\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-20 03:18:37',5),(182,'护理等级',2,'com.zzyl.nursing.controller.NursingLevelController.edit()','PUT',1,'admin','研发部门','/nursing/level','127.0.0.1','内网IP','{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000,\"id\":77,\"lplanId\":134,\"name\":\"1号护理计划\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-20 11:18:45\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-20 03:18:45',4),(183,'代码生成',2,'com.zzyl.generator.controller.GenController.editSave()','PUT',1,'admin','研发部门','/tool/gen','127.0.0.1','内网IP','{\"businessName\":\"projectPlan\",\"className\":\"NursingProjectPlan\",\"columns\":[{\"capJavaField\":\"Id\",\"columnId\":34,\"columnName\":\"id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 07:37:36\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":4,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"PlanId\",\"columnComment\":\"计划id\",\"columnId\":35,\"columnName\":\"plan_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 07:37:36\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"planId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":4,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"ProjectId\",\"columnComment\":\"项目id\",\"columnId\":36,\"columnName\":\"project_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 07:37:36\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"projectId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":4,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"ExecuteTime\",\"columnComment\":\"计划执行时间\",\"columnId\":37,\"columnName\":\"execute_time\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 07:37:36\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"executeTime\",\"javaType\"','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-21 02:39:05',89),(184,'代码生成',2,'com.zzyl.generator.controller.GenController.editSave()','PUT',1,'admin','研发部门','/tool/gen','127.0.0.1','内网IP','{\"businessName\":\"projectPlan\",\"className\":\"NursingProjectPlan\",\"columns\":[{\"capJavaField\":\"Id\",\"columnId\":34,\"columnName\":\"id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 07:37:36\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":4,\"updateBy\":\"\",\"updateTime\":\"2024-08-21 02:39:05\",\"usableColumn\":false},{\"capJavaField\":\"PlanId\",\"columnComment\":\"计划id\",\"columnId\":35,\"columnName\":\"plan_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 07:37:36\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"planId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":4,\"updateBy\":\"\",\"updateTime\":\"2024-08-21 02:39:05\",\"usableColumn\":false},{\"capJavaField\":\"ProjectId\",\"columnComment\":\"项目id\",\"columnId\":36,\"columnName\":\"project_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 07:37:36\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"projectId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":4,\"updateBy\":\"\",\"updateTime\":\"2024-08-21 02:39:05\",\"usableColumn\":false},{\"capJavaField\":\"ExecuteTime\",\"columnComment\":\"计划执行时间\",\"columnId\":37,\"columnName\":\"execute_time\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 07:37:36\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-21 02:39:42',83),(185,'代码生成',2,'com.zzyl.generator.controller.GenController.editSave()','PUT',1,'admin','研发部门','/tool/gen','127.0.0.1','内网IP','{\"businessName\":\"nursingLevel\",\"className\":\"NursingLevel\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键ID\",\"columnId\":14,\"columnName\":\"id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 07:37:35\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":false,\"isIncrement\":\"1\",\"isInsert\":\"0\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-08-14 08:27:28\",\"usableColumn\":false},{\"capJavaField\":\"Name\",\"columnComment\":\"等级名称\",\"columnId\":15,\"columnName\":\"name\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 07:37:35\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"name\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-08-14 08:27:28\",\"usableColumn\":false},{\"capJavaField\":\"LplanId\",\"columnComment\":\"护理计划ID\",\"columnId\":16,\"columnName\":\"lplan_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 07:37:35\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"0\",\"isRequired\":\"0\",\"javaField\":\"lplanId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":3,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-08-14 08:27:28\",\"usableColumn\":false},{\"capJavaField\":\"Fee\",\"columnComment\":\"护理费用\",\"columnId\":17,\"columnName\":\"fee\",\"columnType\":\"decimal(10,2)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 07:37:35\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-21 03:24:12',212),(186,'代码生成',2,'com.zzyl.generator.controller.GenController.editSave()','PUT',1,'admin','研发部门','/tool/gen','127.0.0.1','内网IP','{\"businessName\":\"project\",\"className\":\"NursingProject\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"编号\",\"columnId\":1,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 02:56:15\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":false,\"isIncrement\":\"1\",\"isInsert\":\"0\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":1,\"updateBy\":\"\",\"updateTime\":\"2024-08-14 02:59:29\",\"usableColumn\":false},{\"capJavaField\":\"Name\",\"columnComment\":\"名称\",\"columnId\":2,\"columnName\":\"name\",\"columnType\":\"varchar(100)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 02:56:15\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"name\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":false,\"sort\":2,\"superColumn\":false,\"tableId\":1,\"updateBy\":\"\",\"updateTime\":\"2024-08-14 02:59:29\",\"usableColumn\":false},{\"capJavaField\":\"OrderNo\",\"columnComment\":\"排序号\",\"columnId\":3,\"columnName\":\"order_no\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 02:56:15\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"0\",\"isRequired\":\"0\",\"javaField\":\"orderNo\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":3,\"superColumn\":false,\"tableId\":1,\"updateBy\":\"\",\"updateTime\":\"2024-08-14 02:59:29\",\"usableColumn\":false},{\"capJavaField\":\"Unit\",\"columnComment\":\"单位\",\"columnId\":4,\"columnName\":\"unit\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 02:56:15\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInse','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-21 03:44:32',156),(187,'代码生成',6,'com.zzyl.generator.controller.GenController.importTableSave()','POST',1,'admin','研发部门','/tool/gen/importTable','127.0.0.1','内网IP','{\"tables\":\"check_in\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-21 03:46:38',81),(188,'代码生成',2,'com.zzyl.generator.controller.GenController.editSave()','PUT',1,'admin','研发部门','/tool/gen','127.0.0.1','内网IP','{\"businessName\":\"checkIn\",\"className\":\"CheckIn\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"id\",\"columnId\":45,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-21 03:46:38\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":5,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"CheckInCode\",\"columnComment\":\"编号\",\"columnId\":46,\"columnName\":\"check_in_code\",\"columnType\":\"varchar(255)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-21 03:46:38\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"checkInCode\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":5,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"Title\",\"columnComment\":\"标题\",\"columnId\":47,\"columnName\":\"title\",\"columnType\":\"varchar(255)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-21 03:46:38\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"title\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":5,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"ElderId\",\"columnComment\":\"老人id\",\"columnId\":48,\"columnName\":\"elder_id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-21 03:46:38\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"elderId\"','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-21 03:47:35',70),(189,'菜单管理',1,'com.zzyl.web.controller.system.SysMenuController.add()','POST',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"createBy\":\"admin\",\"icon\":\"date-range\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuName\":\"在住管理\",\"menuType\":\"M\",\"orderNum\":2,\"params\":{},\"parentId\":0,\"path\":\"liveIn\",\"status\":\"0\",\"visible\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-22 06:49:19',26),(190,'菜单管理',1,'com.zzyl.web.controller.system.SysMenuController.add()','POST',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"component\":\"nursing/roomType/index\",\"createBy\":\"admin\",\"icon\":\"size\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuName\":\"房型设置\",\"menuType\":\"C\",\"orderNum\":0,\"params\":{},\"parentId\":2019,\"path\":\"houseSet\",\"status\":\"0\",\"visible\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-22 06:50:50',9),(191,'房型',2,'com.zzyl.nursing.controller.RoomTypeController.edit()','PUT',1,'admin','研发部门','/elder/roomType','127.0.0.1','内网IP','{\"id\":4,\"params\":{},\"status\":0,\"updateBy\":\"1\",\"updateTime\":\"2024-08-22 14:54:22\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-22 06:54:25',23),(192,'房型',2,'com.zzyl.nursing.controller.RoomTypeController.edit()','PUT',1,'admin','研发部门','/elder/roomType','127.0.0.1','内网IP','{\"id\":4,\"params\":{},\"status\":0,\"updateBy\":\"1\",\"updateTime\":\"2024-08-22 14:54:25\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-22 06:54:28',7),(193,'房型',2,'com.zzyl.nursing.controller.RoomTypeController.edit()','PUT',1,'admin','研发部门','/elder/roomType','127.0.0.1','内网IP','{\"id\":4,\"params\":{},\"status\":0,\"updateBy\":\"1\",\"updateTime\":\"2024-08-22 14:54:35\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-22 06:54:38',6),(194,'房型',2,'com.zzyl.nursing.controller.RoomTypeController.edit()','PUT',1,'admin','研发部门','/elder/roomType','127.0.0.1','内网IP','{\"id\":4,\"params\":{},\"status\":0,\"updateBy\":\"1\",\"updateTime\":\"2024-08-22 14:56:59\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-22 06:57:01',29221),(195,'房型',2,'com.zzyl.nursing.controller.RoomTypeController.edit()','PUT',1,'admin','研发部门','/elder/roomType','127.0.0.1','内网IP','{\"id\":4,\"params\":{},\"status\":0,\"updateBy\":\"1\",\"updateTime\":\"2024-08-22 14:58:01\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-22 06:58:04',4065),(196,'房型',2,'com.zzyl.nursing.controller.RoomTypeController.edit()','PUT',1,'admin','研发部门','/elder/roomType','127.0.0.1','内网IP','{\"id\":4,\"params\":{},\"status\":0,\"updateBy\":\"1\",\"updateTime\":\"2024-08-22 16:10:12\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-22 08:10:14',14),(197,'房型',2,'com.zzyl.nursing.controller.RoomTypeController.edit()','PUT',1,'admin','研发部门','/elder/roomType','127.0.0.1','内网IP','{\"id\":4,\"params\":{},\"status\":0,\"updateBy\":\"1\",\"updateTime\":\"2024-08-22 16:10:32\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-22 08:10:35',10),(198,'房型',2,'com.zzyl.nursing.controller.RoomTypeController.edit()','PUT',1,'admin','研发部门','/elder/roomType','127.0.0.1','内网IP','{\"id\":4,\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2024-08-22 16:11:39\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-22 08:11:41',5),(199,'房型',2,'com.zzyl.nursing.controller.RoomTypeController.edit()','PUT',1,'admin','研发部门','/elder/roomType','127.0.0.1','内网IP','{\"id\":4,\"params\":{},\"status\":0,\"updateBy\":\"1\",\"updateTime\":\"2024-08-22 16:11:42\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-22 08:11:44',5),(200,'房型',2,'com.zzyl.nursing.controller.RoomTypeController.edit()','PUT',1,'admin','研发部门','/elder/roomType','127.0.0.1','内网IP','{\"id\":4,\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2024-08-22 16:12:02\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-22 08:12:05',8),(201,'房型',2,'com.zzyl.nursing.controller.RoomTypeController.edit()','PUT',1,'admin','研发部门','/elder/roomType','127.0.0.1','内网IP','{\"id\":4,\"params\":{},\"status\":0,\"updateBy\":\"1\",\"updateTime\":\"2024-08-22 16:12:18\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-22 08:12:21',7),(202,'房型',2,'com.zzyl.nursing.controller.RoomTypeController.edit()','PUT',1,'admin','研发部门','/elder/roomType','127.0.0.1','内网IP','{\"id\":4,\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2024-08-22 16:12:20\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-22 08:12:23',6),(203,'菜单管理',1,'com.zzyl.web.controller.system.SysMenuController.add()','POST',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"component\":\"nursing/floor/index\",\"createBy\":\"admin\",\"icon\":\"tree-table\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuName\":\"床位预览\",\"menuType\":\"C\",\"orderNum\":2,\"params\":{},\"parentId\":2019,\"path\":\"floor\",\"status\":\"0\",\"visible\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-22 08:15:05',14),(204,'楼层',1,'com.zzyl.nursing.controller.FloorController.add()','POST',1,'admin','研发部门','/elder/floor','127.0.0.1','内网IP','{\"code\":1,\"createBy\":\"1\",\"createTime\":\"2024-08-22 16:19:50\",\"id\":411,\"name\":\"88\",\"params\":{}}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-22 08:19:53',13),(205,'楼层',3,'com.zzyl.nursing.controller.FloorController.remove()','DELETE',1,'admin','研发部门','/elder/floor/411','127.0.0.1','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-22 08:29:18',14),(206,'房间',1,'com.zzyl.nursing.controller.RoomController.add()','POST',1,'admin','研发部门','/elder/room','127.0.0.1','内网IP','{\"code\":\"102-2\",\"createBy\":\"1\",\"createTime\":\"2024-08-22 18:49:20\",\"floorId\":406,\"id\":86,\"params\":{},\"sort\":1,\"typeName\":\"豪华单人间\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-22 10:49:23',13),(207,'房型',2,'com.zzyl.nursing.controller.RoomTypeController.edit()','PUT',1,'admin','研发部门','/elder/roomType','127.0.0.1','内网IP','{\"id\":105,\"params\":{},\"status\":0,\"updateBy\":\"1\",\"updateTime\":\"2024-08-22 19:05:25\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-22 11:05:28',6),(208,'房型',3,'com.zzyl.nursing.controller.RoomTypeController.remove()','DELETE',1,'admin','研发部门','/elder/roomType/105','127.0.0.1','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-22 11:05:30',6),(209,'房型',3,'com.zzyl.nursing.controller.RoomTypeController.remove()','DELETE',1,'admin','研发部门','/elder/roomType/109','127.0.0.1','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-22 11:05:33',5),(210,'房型',3,'com.zzyl.nursing.controller.RoomTypeController.remove()','DELETE',1,'admin','研发部门','/elder/roomType/114','127.0.0.1','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-22 11:05:38',5),(211,'房型',3,'com.zzyl.nursing.controller.RoomTypeController.remove()','DELETE',1,'admin','研发部门','/elder/roomType/112','127.0.0.1','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-22 11:05:41',5),(212,'房型',3,'com.zzyl.nursing.controller.RoomTypeController.remove()','DELETE',1,'admin','研发部门','/elder/roomType/113','127.0.0.1','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-22 11:05:46',5),(213,'房型',3,'com.zzyl.nursing.controller.RoomTypeController.remove()','DELETE',1,'admin','研发部门','/elder/roomType/111','127.0.0.1','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-22 11:05:51',5),(214,'房型',2,'com.zzyl.nursing.controller.RoomTypeController.edit()','PUT',1,'admin','研发部门','/elder/roomType','127.0.0.1','内网IP','{\"id\":110,\"params\":{},\"status\":0,\"updateBy\":\"1\",\"updateTime\":\"2024-08-22 19:05:50\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-22 11:05:53',5),(215,'房型',2,'com.zzyl.nursing.controller.RoomTypeController.edit()','PUT',1,'admin','研发部门','/elder/roomType','127.0.0.1','内网IP','{\"id\":110,\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2024-08-22 19:05:52\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-22 11:05:55',4),(216,'房型',2,'com.zzyl.nursing.controller.RoomTypeController.edit()','PUT',1,'admin','研发部门','/elder/roomType','127.0.0.1','内网IP','{\"bedCount\":5,\"createBy\":\"1671403256519078138\",\"createTime\":\"2023-12-27 00:07:07\",\"id\":110,\"introduction\":\"12312312312312312312312312312312312312312312312312\",\"name\":\"测试修改\",\"params\":{},\"photo\":\"https://yjy-slwl-oss.oss-cn-hangzhou.aliyuncs.com/00167193-00f1-49a6-85e5-74dd0b93819e.png\",\"price\":1000,\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2024-08-22 19:05:53\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-22 11:06:10',9),(217,'房型',1,'com.zzyl.nursing.controller.RoomTypeController.add()','POST',1,'admin','研发部门','/elder/roomType','127.0.0.1','内网IP','{\"bedCount\":10,\"createBy\":\"1\",\"createTime\":\"2024-08-22 19:06:33\",\"id\":115,\"introduction\":\"水电费方式\",\"name\":\"测试新增\",\"params\":{},\"photo\":\"https://itheim.oss-cn-beijing.aliyuncs.com/8fe7b29d-fce0-4201-becb-0586e8284a9d.png\",\"price\":3500,\"remark\":\"是否\",\"status\":0}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-22 11:06:36',7),(218,'房型',2,'com.zzyl.nursing.controller.RoomTypeController.edit()','PUT',1,'admin','研发部门','/elder/roomType','127.0.0.1','内网IP','{\"id\":115,\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2024-08-22 19:06:41\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-22 11:06:44',5),(219,'楼层',1,'com.zzyl.nursing.controller.FloorController.add()','POST',1,'admin','研发部门','/elder/floor','127.0.0.1','内网IP','{\"code\":1,\"createBy\":\"1\",\"createTime\":\"2024-08-22 19:06:55\",\"id\":412,\"name\":\"13楼\",\"params\":{}}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-22 11:06:58',4),(220,'房间',1,'com.zzyl.nursing.controller.RoomController.add()','POST',1,'admin','研发部门','/elder/room','127.0.0.1','内网IP','{\"code\":\"1301\",\"createBy\":\"1\",\"createTime\":\"2024-08-22 19:07:05\",\"floorId\":412,\"id\":87,\"params\":{},\"sort\":1,\"typeName\":\"双人套房\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-22 11:07:07',8),(221,'床位',1,'com.zzyl.nursing.controller.BedController.add()','POST',1,'admin','研发部门','/elder/bed','127.0.0.1','内网IP','{\"bedNumber\":\"1301-1\",\"createBy\":\"1\",\"createTime\":\"2024-08-22 19:07:15\",\"id\":197,\"params\":{},\"roomId\":87,\"sort\":1}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-22 11:07:18',7),(222,'床位',1,'com.zzyl.nursing.controller.BedController.add()','POST',1,'admin','研发部门','/elder/bed','127.0.0.1','内网IP','{\"bedNumber\":\"1301-2\",\"createBy\":\"1\",\"createTime\":\"2024-08-22 19:07:22\",\"id\":198,\"params\":{},\"roomId\":87,\"sort\":1}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-22 11:07:25',4),(223,'床位',2,'com.zzyl.nursing.controller.BedController.edit()','PUT',1,'admin','研发部门','/elder/bed','127.0.0.1','内网IP','{\"bedNumber\":\"1301-7\",\"id\":197,\"params\":{},\"roomId\":87,\"sort\":1,\"updateBy\":\"1\",\"updateTime\":\"2024-08-22 19:07:28\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-22 11:07:31',7),(224,'床位',3,'com.zzyl.nursing.controller.BedController.remove()','DELETE',1,'admin','研发部门','/elder/bed/197','127.0.0.1','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-22 11:07:34',9),(225,'床位',3,'com.zzyl.nursing.controller.BedController.remove()','DELETE',1,'admin','研发部门','/elder/bed/198','127.0.0.1','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-22 11:07:37',6),(226,'房间',2,'com.zzyl.nursing.controller.RoomController.edit()','PUT',1,'admin','研发部门','/elder/room','127.0.0.1','内网IP','{\"code\":\"1302\",\"id\":87,\"params\":{},\"sort\":1,\"typeName\":\"豪华双人间\",\"updateBy\":\"1\",\"updateTime\":\"2024-08-22 19:07:43\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-22 11:07:46',6),(227,'房间',3,'com.zzyl.nursing.controller.RoomController.remove()','DELETE',1,'admin','研发部门','/elder/room/87','127.0.0.1','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-22 11:07:52',6),(228,'楼层',3,'com.zzyl.nursing.controller.FloorController.remove()','DELETE',1,'admin','研发部门','/elder/floor/412','127.0.0.1','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-22 11:07:56',6),(229,'菜单管理',2,'com.zzyl.web.controller.system.SysMenuController.edit()','PUT',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"component\":\"serve/project/index\",\"createTime\":\"2024-08-14 03:00:15\",\"icon\":\"color\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2001,\"menuName\":\"护理项目\",\"menuType\":\"C\",\"orderNum\":1,\"params\":{},\"parentId\":2000,\"path\":\"project\",\"perms\":\"serve:project:list\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-22 12:16:12',11),(230,'菜单管理',2,'com.zzyl.web.controller.system.SysMenuController.edit()','PUT',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"component\":\"nursing/nursingLevel/index\",\"createTime\":\"2024-08-14 08:29:05\",\"icon\":\"guide\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2007,\"menuName\":\"护理等级\",\"menuType\":\"C\",\"orderNum\":1,\"params\":{},\"parentId\":2000,\"path\":\"nursingLevel\",\"perms\":\"nursing:nursingLevel:list\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-22 12:16:22',7),(231,'菜单管理',2,'com.zzyl.web.controller.system.SysMenuController.edit()','PUT',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"component\":\"nursing/nursingPlan/index\",\"createTime\":\"2024-08-14 08:29:10\",\"icon\":\"druid\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2013,\"menuName\":\"护理计划\",\"menuType\":\"C\",\"orderNum\":1,\"params\":{},\"parentId\":2000,\"path\":\"nursingPlan\",\"perms\":\"nursing:nursingPlan:list\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-22 12:16:43',10),(232,'代码生成',3,'com.zzyl.generator.controller.GenController.remove()','DELETE',1,'admin','研发部门','/tool/gen/5','127.0.0.1','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-23 12:21:12',41),(233,'代码生成',3,'com.zzyl.generator.controller.GenController.remove()','DELETE',1,'admin','研发部门','/tool/gen/4','127.0.0.1','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-23 12:21:18',13),(234,'代码生成',3,'com.zzyl.generator.controller.GenController.remove()','DELETE',1,'admin','研发部门','/tool/gen/3','127.0.0.1','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-23 12:21:20',16),(235,'代码生成',3,'com.zzyl.generator.controller.GenController.remove()','DELETE',1,'admin','研发部门','/tool/gen/2','127.0.0.1','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-23 12:21:22',12),(236,'代码生成',3,'com.zzyl.generator.controller.GenController.remove()','DELETE',1,'admin','研发部门','/tool/gen/1','127.0.0.1','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-23 12:21:24',12),(237,'代码生成',6,'com.zzyl.generator.controller.GenController.importTableSave()','POST',1,'admin','研发部门','/tool/gen/importTable','127.0.0.1','内网IP','{\"tables\":\"contract,check_in_config,check_in,elder\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-23 12:21:32',364),(238,'代码生成',2,'com.zzyl.generator.controller.GenController.editSave()','PUT',1,'admin','研发部门','/tool/gen','127.0.0.1','内网IP','{\"businessName\":\"checkIn\",\"className\":\"CheckIn\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键ID\",\"columnId\":58,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":6,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"ElderId\",\"columnComment\":\"老人ID\",\"columnId\":59,\"columnName\":\"elder_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"elderId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":6,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"IdNumber\",\"columnComment\":\"身份证号\",\"columnId\":60,\"columnName\":\"id_number\",\"columnType\":\"varchar(18)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"idNumber\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":6,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"StartDate\",\"columnComment\":\"入住开始时间\",\"columnId\":61,\"columnName\":\"start_date\",\"columnType\":\"datetime\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"datetime\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"startD','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-23 12:22:45',76),(239,'代码生成',2,'com.zzyl.generator.controller.GenController.editSave()','PUT',1,'admin','研发部门','/tool/gen','127.0.0.1','内网IP','{\"businessName\":\"checkInConfig\",\"className\":\"CheckInConfig\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键ID\",\"columnId\":72,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":7,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"CheckInId\",\"columnComment\":\"入住表ID\",\"columnId\":73,\"columnName\":\"check_in_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"checkInId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":7,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"CareLevelId\",\"columnComment\":\"护理等级ID\",\"columnId\":74,\"columnName\":\"care_level_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"careLevelId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":7,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"CareLevelName\",\"columnComment\":\"护理等级名称\",\"columnId\":75,\"columnName\":\"care_level_name\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRe','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-23 12:23:31',81),(240,'代码生成',2,'com.zzyl.generator.controller.GenController.editSave()','PUT',1,'admin','研发部门','/tool/gen','127.0.0.1','内网IP','{\"businessName\":\"contract\",\"className\":\"Contract\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键ID\",\"columnId\":90,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":8,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"ElderId\",\"columnComment\":\"老人ID\",\"columnId\":91,\"columnName\":\"elder_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"elderId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":8,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"ContractName\",\"columnComment\":\"合同名称\",\"columnId\":92,\"columnName\":\"contract_name\",\"columnType\":\"varchar(100)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"contractName\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":8,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"ContractNumber\",\"columnComment\":\"合同编号\",\"columnId\":93,\"columnName\":\"contract_number\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-23 12:23:58',87),(241,'代码生成',2,'com.zzyl.generator.controller.GenController.editSave()','PUT',1,'admin','研发部门','/tool/gen','127.0.0.1','内网IP','{\"businessName\":\"elder\",\"className\":\"Elder\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"id\",\"columnId\":111,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":9,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"Name\",\"columnComment\":\"名称\",\"columnId\":112,\"columnName\":\"name\",\"columnType\":\"varchar(255)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"name\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":false,\"sort\":2,\"superColumn\":false,\"tableId\":9,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"Image\",\"columnComment\":\"图片\",\"columnId\":113,\"columnName\":\"image\",\"columnType\":\"varchar(255)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"imageUpload\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"image\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":false,\"sort\":3,\"superColumn\":false,\"tableId\":9,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"IdCardNo\",\"columnComment\":\"身份证号\",\"columnId\":114,\"columnName\":\"id_card_no\",\"columnType\":\"varchar(20)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"idCardNo\",\"ja','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-23 12:24:18',73),(242,'代码生成',2,'com.zzyl.generator.controller.GenController.editSave()','PUT',1,'admin','研发部门','/tool/gen','127.0.0.1','内网IP','{\"businessName\":\"checkIn\",\"className\":\"CheckIn\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键ID\",\"columnId\":58,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":6,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 12:22:45\",\"usableColumn\":false},{\"capJavaField\":\"ElderId\",\"columnComment\":\"老人ID\",\"columnId\":59,\"columnName\":\"elder_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"elderId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":6,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 12:22:45\",\"usableColumn\":false},{\"capJavaField\":\"IdNumber\",\"columnComment\":\"身份证号\",\"columnId\":60,\"columnName\":\"id_number\",\"columnType\":\"varchar(18)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"idNumber\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":6,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 12:22:45\",\"usableColumn\":false},{\"capJavaField\":\"StartDate\",\"columnComment\":\"入住开始时间\",\"columnId\":61,\"columnName\":\"start_date\",\"columnType\":\"datetime\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"datetime\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"i','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-23 12:26:43',97),(243,'代码生成',2,'com.zzyl.generator.controller.GenController.editSave()','PUT',1,'admin','研发部门','/tool/gen','127.0.0.1','内网IP','{\"businessName\":\"checkInConfig\",\"className\":\"CheckInConfig\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键ID\",\"columnId\":72,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":7,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 12:23:31\",\"usableColumn\":false},{\"capJavaField\":\"CheckInId\",\"columnComment\":\"入住表ID\",\"columnId\":73,\"columnName\":\"check_in_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"checkInId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":7,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 12:23:31\",\"usableColumn\":false},{\"capJavaField\":\"CareLevelId\",\"columnComment\":\"护理等级ID\",\"columnId\":74,\"columnName\":\"care_level_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"careLevelId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":7,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 12:23:31\",\"usableColumn\":false},{\"capJavaField\":\"CareLevelName\",\"columnComment\":\"护理等级名称\",\"columnId\":75,\"columnName\":\"care_level_name\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":fals','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-23 12:27:19',74),(244,'代码生成',2,'com.zzyl.generator.controller.GenController.editSave()','PUT',1,'admin','研发部门','/tool/gen','127.0.0.1','内网IP','{\"businessName\":\"contract\",\"className\":\"Contract\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键ID\",\"columnId\":90,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":8,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 12:23:58\",\"usableColumn\":false},{\"capJavaField\":\"ElderId\",\"columnComment\":\"老人ID\",\"columnId\":91,\"columnName\":\"elder_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"elderId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":8,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 12:23:58\",\"usableColumn\":false},{\"capJavaField\":\"ContractName\",\"columnComment\":\"合同名称\",\"columnId\":92,\"columnName\":\"contract_name\",\"columnType\":\"varchar(100)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"contractName\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":8,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 12:23:58\",\"usableColumn\":false},{\"capJavaField\":\"ContractNumber\",\"columnComment\":\"合同编号\",\"columnId\":93,\"columnName\":\"contract_number\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"ins','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-23 12:27:57',88),(245,'代码生成',2,'com.zzyl.generator.controller.GenController.editSave()','PUT',1,'admin','研发部门','/tool/gen','127.0.0.1','内网IP','{\"businessName\":\"elder\",\"className\":\"Elder\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"id\",\"columnId\":111,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":9,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 12:24:18\",\"usableColumn\":false},{\"capJavaField\":\"Name\",\"columnComment\":\"名称\",\"columnId\":112,\"columnName\":\"name\",\"columnType\":\"varchar(255)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"name\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":false,\"sort\":2,\"superColumn\":false,\"tableId\":9,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 12:24:18\",\"usableColumn\":false},{\"capJavaField\":\"Image\",\"columnComment\":\"图片\",\"columnId\":113,\"columnName\":\"image\",\"columnType\":\"varchar(255)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"imageUpload\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"image\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":false,\"sort\":3,\"superColumn\":false,\"tableId\":9,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 12:24:18\",\"usableColumn\":false},{\"capJavaField\":\"IdCardNo\",\"columnComment\":\"身份证号\",\"columnId\":114,\"columnName\":\"id_card_no\",\"columnType\":\"varchar(20)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrem','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-23 12:28:53',72),(246,'代码生成',8,'com.zzyl.generator.controller.GenController.batchGenCode()','GET',1,'admin','研发部门','/tool/gen/batchGenCode','127.0.0.1','内网IP','{\"tables\":\"check_in,check_in_config,contract,elder\"}','',0,'','2024-08-23 12:35:43',748),(247,'菜单管理',1,'com.zzyl.web.controller.system.SysMenuController.add()','POST',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"createBy\":\"admin\",\"icon\":\"component\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuName\":\"入退管理\",\"menuType\":\"M\",\"orderNum\":3,\"params\":{},\"parentId\":0,\"path\":\"enterQuit\",\"status\":\"0\",\"visible\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-23 12:52:34',34),(248,'代码生成',2,'com.zzyl.generator.controller.GenController.editSave()','PUT',1,'admin','研发部门','/tool/gen','127.0.0.1','内网IP','{\"businessName\":\"checkIn\",\"className\":\"CheckIn\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键ID\",\"columnId\":58,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":6,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 12:26:43\",\"usableColumn\":false},{\"capJavaField\":\"ElderId\",\"columnComment\":\"老人ID\",\"columnId\":59,\"columnName\":\"elder_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"elderId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":6,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 12:26:43\",\"usableColumn\":false},{\"capJavaField\":\"IdNumber\",\"columnComment\":\"身份证号\",\"columnId\":60,\"columnName\":\"id_number\",\"columnType\":\"varchar(18)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"idNumber\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":6,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 12:26:43\",\"usableColumn\":false},{\"capJavaField\":\"StartDate\",\"columnComment\":\"入住开始时间\",\"columnId\":61,\"columnName\":\"start_date\",\"columnType\":\"datetime\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"datetime\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"i','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-23 12:57:16',152),(249,'代码生成',2,'com.zzyl.generator.controller.GenController.editSave()','PUT',1,'admin','研发部门','/tool/gen','127.0.0.1','内网IP','{\"businessName\":\"contract\",\"className\":\"Contract\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键ID\",\"columnId\":90,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":8,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 12:27:57\",\"usableColumn\":false},{\"capJavaField\":\"ElderId\",\"columnComment\":\"老人ID\",\"columnId\":91,\"columnName\":\"elder_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"elderId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":8,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 12:27:57\",\"usableColumn\":false},{\"capJavaField\":\"ContractName\",\"columnComment\":\"合同名称\",\"columnId\":92,\"columnName\":\"contract_name\",\"columnType\":\"varchar(100)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"contractName\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":8,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 12:27:57\",\"usableColumn\":false},{\"capJavaField\":\"ContractNumber\",\"columnComment\":\"合同编号\",\"columnId\":93,\"columnName\":\"contract_number\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"ins','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-23 12:58:53',124),(250,'代码生成',8,'com.zzyl.generator.controller.GenController.batchGenCode()','GET',1,'admin','研发部门','/tool/gen/batchGenCode','127.0.0.1','内网IP','{\"tables\":\"check_in,check_in_config,contract,elder\"}','',0,'','2024-08-23 13:00:15',629),(251,'代码生成',2,'com.zzyl.generator.controller.GenController.synchDb()','GET',1,'admin','研发部门','/tool/gen/synchDb/check_in','127.0.0.1','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-23 13:28:23',157),(252,'代码生成',2,'com.zzyl.generator.controller.GenController.synchDb()','GET',1,'admin','研发部门','/tool/gen/synchDb/contract','127.0.0.1','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-23 13:28:27',141),(253,'代码生成',2,'com.zzyl.generator.controller.GenController.synchDb()','GET',1,'admin','研发部门','/tool/gen/synchDb/check_in_config','127.0.0.1','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-23 13:28:34',115),(254,'代码生成',2,'com.zzyl.generator.controller.GenController.editSave()','PUT',1,'admin','研发部门','/tool/gen','127.0.0.1','内网IP','{\"businessName\":\"contract\",\"className\":\"Contract\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键ID\",\"columnId\":90,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":8,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 13:28:27\",\"usableColumn\":false},{\"capJavaField\":\"ElderId\",\"columnComment\":\"老人ID\",\"columnId\":91,\"columnName\":\"elder_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"elderId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":8,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 13:28:27\",\"usableColumn\":false},{\"capJavaField\":\"ContractName\",\"columnComment\":\"合同名称\",\"columnId\":92,\"columnName\":\"contract_name\",\"columnType\":\"varchar(100)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"contractName\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":8,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 13:28:27\",\"usableColumn\":false},{\"capJavaField\":\"ContractNumber\",\"columnComment\":\"合同编号\",\"columnId\":93,\"columnName\":\"contract_number\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"ins','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-23 13:29:42',124),(255,'代码生成',2,'com.zzyl.generator.controller.GenController.editSave()','PUT',1,'admin','研发部门','/tool/gen','127.0.0.1','内网IP','{\"businessName\":\"checkInConfig\",\"className\":\"CheckInConfig\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键ID\",\"columnId\":72,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":7,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 13:28:34\",\"usableColumn\":false},{\"capJavaField\":\"CheckInId\",\"columnComment\":\"入住表ID\",\"columnId\":73,\"columnName\":\"check_in_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"checkInId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":7,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 13:28:34\",\"usableColumn\":false},{\"capJavaField\":\"CareLevelId\",\"columnComment\":\"护理等级ID\",\"columnId\":74,\"columnName\":\"care_level_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"careLevelId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":7,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 13:28:34\",\"usableColumn\":false},{\"capJavaField\":\"CareLevelName\",\"columnComment\":\"护理等级名称\",\"columnId\":75,\"columnName\":\"care_level_name\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":fals','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-23 13:30:20',88),(256,'代码生成',3,'com.zzyl.generator.controller.GenController.remove()','DELETE',1,'admin','研发部门','/tool/gen/7,6','127.0.0.1','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-23 13:30:49',20),(257,'代码生成',6,'com.zzyl.generator.controller.GenController.importTableSave()','POST',1,'admin','研发部门','/tool/gen/importTable','127.0.0.1','内网IP','{\"tables\":\"check_in_config,check_in\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-23 13:30:56',138),(258,'代码生成',3,'com.zzyl.generator.controller.GenController.remove()','DELETE',1,'admin','研发部门','/tool/gen/10,11','127.0.0.1','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-23 13:32:19',15),(259,'代码生成',6,'com.zzyl.generator.controller.GenController.importTableSave()','POST',1,'admin','研发部门','/tool/gen/importTable','127.0.0.1','内网IP','{\"tables\":\"check_in_config,check_in\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-23 13:32:24',124),(260,'代码生成',2,'com.zzyl.generator.controller.GenController.editSave()','PUT',1,'admin','研发部门','/tool/gen','127.0.0.1','内网IP','{\"businessName\":\"checkIn\",\"className\":\"CheckIn\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键ID\",\"columnId\":161,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 13:32:23\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":12,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"ElderId\",\"columnComment\":\"老人ID\",\"columnId\":162,\"columnName\":\"elder_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 13:32:23\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"elderId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":12,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"IdCardNo\",\"columnComment\":\"身份证号\",\"columnId\":163,\"columnName\":\"id_card_no\",\"columnType\":\"char(18)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 13:32:23\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"idCardNo\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":12,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"StartDate\",\"columnComment\":\"入住开始时间\",\"columnId\":164,\"columnName\":\"start_date\",\"columnType\":\"date\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 13:32:23\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"datetime\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"start','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-23 13:33:23',60),(261,'代码生成',2,'com.zzyl.generator.controller.GenController.editSave()','PUT',1,'admin','研发部门','/tool/gen','127.0.0.1','内网IP','{\"businessName\":\"check_in_config\",\"className\":\"CheckInConfig\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键ID\",\"columnId\":175,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 13:32:23\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":13,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"CheckInId\",\"columnComment\":\"入住表ID\",\"columnId\":176,\"columnName\":\"check_in_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 13:32:23\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"checkInId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":13,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"NursingLevelId\",\"columnComment\":\"护理等级ID\",\"columnId\":177,\"columnName\":\"nursing_level_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 13:32:23\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"nursingLevelId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":13,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"NursingLevelName\",\"columnComment\":\"护理等级名称\",\"columnId\":178,\"columnName\":\"nursing_level_name\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 13:32:23\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\"','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-23 13:34:17',85),(262,'代码生成',8,'com.zzyl.generator.controller.GenController.batchGenCode()','GET',1,'admin','研发部门','/tool/gen/batchGenCode','127.0.0.1','内网IP','{\"tables\":\"check_in,check_in_config\"}','',0,'','2024-08-23 13:34:27',332),(263,'代码生成',3,'com.zzyl.generator.controller.GenController.remove()','DELETE',1,'admin','研发部门','/tool/gen/13,12','127.0.0.1','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-23 14:07:17',36),(264,'代码生成',6,'com.zzyl.generator.controller.GenController.importTableSave()','POST',1,'admin','研发部门','/tool/gen/importTable','127.0.0.1','内网IP','{\"tables\":\"check_in_config,check_in\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-23 14:07:25',220),(265,'代码生成',2,'com.zzyl.generator.controller.GenController.editSave()','PUT',1,'admin','研发部门','/tool/gen','127.0.0.1','内网IP','{\"businessName\":\"checkIn\",\"className\":\"CheckIn\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键ID\",\"columnId\":193,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 14:07:25\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":14,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"ElderName\",\"columnComment\":\"老人姓名\",\"columnId\":194,\"columnName\":\"elder_name\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 14:07:25\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"elderName\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":14,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"ElderId\",\"columnComment\":\"老人ID\",\"columnId\":195,\"columnName\":\"elder_id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 14:07:25\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"elderId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":14,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"IdCardNo\",\"columnComment\":\"身份证号\",\"columnId\":196,\"columnName\":\"id_card_no\",\"columnType\":\"char(18)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 14:07:25\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-23 14:09:15',103),(266,'代码生成',2,'com.zzyl.generator.controller.GenController.editSave()','PUT',1,'admin','研发部门','/tool/gen','127.0.0.1','内网IP','{\"businessName\":\"checkInConfig\",\"className\":\"CheckInConfig\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键ID\",\"columnId\":208,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 14:07:25\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":15,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"CheckInId\",\"columnComment\":\"入住表ID\",\"columnId\":209,\"columnName\":\"check_in_id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 14:07:25\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"checkInId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":15,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"NursingLevelId\",\"columnComment\":\"护理等级ID\",\"columnId\":210,\"columnName\":\"nursing_level_id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 14:07:25\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"nursingLevelId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":15,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"NursingLevelName\",\"columnComment\":\"护理等级名称\",\"columnId\":211,\"columnName\":\"nursing_level_name\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 14:07:25\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"i','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-23 14:10:08',114),(267,'代码生成',2,'com.zzyl.generator.controller.GenController.editSave()','PUT',1,'admin','研发部门','/tool/gen','127.0.0.1','内网IP','{\"businessName\":\"checkIn\",\"className\":\"CheckIn\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键ID\",\"columnId\":193,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 14:07:25\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":14,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 14:09:15\",\"usableColumn\":false},{\"capJavaField\":\"ElderName\",\"columnComment\":\"老人姓名\",\"columnId\":194,\"columnName\":\"elder_name\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 14:07:25\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"elderName\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":14,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 14:09:15\",\"usableColumn\":false},{\"capJavaField\":\"ElderId\",\"columnComment\":\"老人ID\",\"columnId\":195,\"columnName\":\"elder_id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 14:07:25\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"elderId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":14,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 14:09:15\",\"usableColumn\":false},{\"capJavaField\":\"IdCardNo\",\"columnComment\":\"身份证号\",\"columnId\":196,\"columnName\":\"id_card_no\",\"columnType\":\"char(18)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 14:07:25\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdi','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-23 14:10:18',80),(268,'代码生成',8,'com.zzyl.generator.controller.GenController.batchGenCode()','GET',1,'admin','研发部门','/tool/gen/batchGenCode','127.0.0.1','内网IP','{\"tables\":\"check_in,check_in_config\"}','',0,'','2024-08-23 14:10:23',420),(269,'菜单管理',2,'com.zzyl.web.controller.system.SysMenuController.edit()','PUT',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"component\":\"nursing/checkIn/index\",\"createTime\":\"2024-08-23 13:13:48\",\"icon\":\"edit\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2023,\"menuName\":\"入住办理\",\"menuType\":\"C\",\"orderNum\":1,\"params\":{},\"parentId\":2022,\"path\":\"checkIn\",\"perms\":\"nursing:checkIn:list\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-24 02:58:12',37),(270,'菜单管理',1,'com.zzyl.web.controller.system.SysMenuController.add()','POST',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"component\":\"nursing/checkIn/details\",\"createBy\":\"admin\",\"icon\":\"checkbox\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuName\":\"入住详情\",\"menuType\":\"C\",\"orderNum\":0,\"params\":{},\"parentId\":2022,\"path\":\"checkInInfo\",\"status\":\"0\",\"visible\":\"1\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-24 03:44:48',12),(271,'菜单管理',2,'com.zzyl.web.controller.system.SysMenuController.edit()','PUT',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"createTime\":\"2024-08-14 02:48:23\",\"icon\":\"system\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":1,\"menuName\":\"系统管理\",\"menuType\":\"M\",\"orderNum\":6,\"params\":{},\"parentId\":0,\"path\":\"system\",\"perms\":\"\",\"query\":\"\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-29 06:40:54',20),(272,'菜单管理',2,'com.zzyl.web.controller.system.SysMenuController.edit()','PUT',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"createTime\":\"2024-08-14 02:48:23\",\"icon\":\"monitor\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2,\"menuName\":\"系统监控\",\"menuType\":\"M\",\"orderNum\":7,\"params\":{},\"parentId\":0,\"path\":\"monitor\",\"perms\":\"\",\"query\":\"\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-29 06:41:07',9),(273,'菜单管理',2,'com.zzyl.web.controller.system.SysMenuController.edit()','PUT',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"createTime\":\"2024-08-14 02:48:23\",\"icon\":\"tool\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":3,\"menuName\":\"系统工具\",\"menuType\":\"M\",\"orderNum\":8,\"params\":{},\"parentId\":0,\"path\":\"tool\",\"perms\":\"\",\"query\":\"\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-29 06:41:14',10),(274,'菜单管理',1,'com.zzyl.web.controller.system.SysMenuController.add()','POST',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"createBy\":\"admin\",\"icon\":\"button\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuName\":\"来访管理\",\"menuType\":\"M\",\"orderNum\":1,\"params\":{},\"parentId\":0,\"path\":\"appointment\",\"status\":\"0\",\"visible\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-29 06:41:45',10),(275,'菜单管理',2,'com.zzyl.web.controller.system.SysMenuController.edit()','PUT',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"createTime\":\"2024-08-23 12:52:34\",\"icon\":\"component\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2022,\"menuName\":\"入退管理\",\"menuType\":\"M\",\"orderNum\":2,\"params\":{},\"parentId\":0,\"path\":\"enterQuit\",\"perms\":\"\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-29 06:42:15',11),(276,'菜单管理',2,'com.zzyl.web.controller.system.SysMenuController.edit()','PUT',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"createTime\":\"2024-08-22 06:49:19\",\"icon\":\"date-range\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2019,\"menuName\":\"在住管理\",\"menuType\":\"M\",\"orderNum\":3,\"params\":{},\"parentId\":0,\"path\":\"liveIn\",\"perms\":\"\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-29 06:42:27',9),(277,'菜单管理',2,'com.zzyl.web.controller.system.SysMenuController.edit()','PUT',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"createTime\":\"2024-08-14 02:59:12\",\"icon\":\"example\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2000,\"menuName\":\"服务管理\",\"menuType\":\"M\",\"orderNum\":4,\"params\":{},\"parentId\":0,\"path\":\"serve\",\"perms\":\"\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-29 06:42:37',11),(278,'菜单管理',1,'com.zzyl.web.controller.system.SysMenuController.add()','POST',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"createBy\":\"admin\",\"icon\":\"exit-fullscreen\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuName\":\"智能监测\",\"menuType\":\"M\",\"orderNum\":5,\"params\":{},\"parentId\":0,\"path\":\"intelligence\",\"status\":\"0\",\"visible\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-29 06:43:14',10),(279,'菜单管理',1,'com.zzyl.web.controller.system.SysMenuController.add()','POST',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"component\":\"nursing/reservation/index\",\"createBy\":\"admin\",\"icon\":\"dashboard\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuName\":\"预约信息\",\"menuType\":\"C\",\"orderNum\":1,\"params\":{},\"parentId\":2036,\"path\":\"reservation\",\"status\":\"0\",\"visible\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-29 06:47:29',10),(280,'菜单管理',1,'com.zzyl.web.controller.system.SysMenuController.add()','POST',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"component\":\"nursing/healthAssessment/index\",\"createBy\":\"admin\",\"icon\":\"eye\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuName\":\"健康评估\",\"menuType\":\"C\",\"orderNum\":1,\"params\":{},\"parentId\":2022,\"path\":\"healthAssessment\",\"status\":\"0\",\"visible\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-29 06:48:51',9),(281,'菜单管理',1,'com.zzyl.web.controller.system.SysMenuController.add()','POST',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"component\":\"nursing/healthAssessment/details\",\"createBy\":\"admin\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuName\":\"评估详情\",\"menuType\":\"C\",\"orderNum\":2,\"params\":{},\"parentId\":2022,\"path\":\"healthDetails\",\"status\":\"0\",\"visible\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-29 06:49:53',10),(282,'菜单管理',2,'com.zzyl.web.controller.system.SysMenuController.edit()','PUT',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"component\":\"nursing/healthAssessment/details\",\"createTime\":\"2024-08-29 06:49:53\",\"icon\":\"#\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2040,\"menuName\":\"评估详情\",\"menuType\":\"C\",\"orderNum\":2,\"params\":{},\"parentId\":2022,\"path\":\"healthDetails\",\"perms\":\"\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"1\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-29 06:50:06',9),(283,'菜单管理',1,'com.zzyl.web.controller.system.SysMenuController.add()','POST',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"component\":\"nursing/oldPeople/index\",\"createBy\":\"admin\",\"icon\":\"peoples\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuName\":\"负责老师\",\"menuType\":\"C\",\"orderNum\":4,\"params\":{},\"parentId\":2000,\"path\":\"oldPeople\",\"status\":\"0\",\"visible\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-29 06:52:12',9),(284,'菜单管理',2,'com.zzyl.web.controller.system.SysMenuController.edit()','PUT',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"component\":\"nursing/oldPeople/index\",\"createTime\":\"2024-08-29 06:52:12\",\"icon\":\"peoples\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2041,\"menuName\":\"负责老人\",\"menuType\":\"C\",\"orderNum\":4,\"params\":{},\"parentId\":2000,\"path\":\"oldPeople\",\"perms\":\"\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-29 06:52:23',8),(285,'菜单管理',1,'com.zzyl.web.controller.system.SysMenuController.add()','POST',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"component\":\"nursing/arrange/index\",\"createBy\":\"admin\",\"icon\":\"redis-list\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuName\":\"任务安排\",\"menuType\":\"C\",\"orderNum\":5,\"params\":{},\"parentId\":2000,\"path\":\"arrange\",\"status\":\"0\",\"visible\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-29 06:53:06',8),(286,'菜单管理',1,'com.zzyl.web.controller.system.SysMenuController.add()','POST',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"component\":\"nursing/arrange/details\",\"createBy\":\"admin\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuName\":\"任务安排详情\",\"menuType\":\"C\",\"orderNum\":1,\"params\":{},\"parentId\":2000,\"path\":\"arrangeDetails\",\"status\":\"0\",\"visible\":\"1\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-29 06:53:37',11),(287,'菜单管理',1,'com.zzyl.web.controller.system.SysMenuController.add()','POST',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"component\":\"nursing/device/index\",\"createBy\":\"admin\",\"icon\":\"tool\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuName\":\"设备管理\",\"menuType\":\"C\",\"orderNum\":0,\"params\":{},\"parentId\":2037,\"path\":\"device\",\"status\":\"0\",\"visible\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-29 06:54:54',8),(288,'菜单管理',1,'com.zzyl.web.controller.system.SysMenuController.add()','POST',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"component\":\"nursing/device/details\",\"createBy\":\"admin\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuName\":\"设备详情\",\"menuType\":\"C\",\"orderNum\":0,\"params\":{},\"parentId\":2037,\"path\":\"details\",\"status\":\"0\",\"visible\":\"1\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-29 06:55:25',9),(289,'菜单管理',1,'com.zzyl.web.controller.system.SysMenuController.add()','POST',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"component\":\"nursing/alertRule/details\",\"createBy\":\"admin\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuName\":\"新增报警规则\",\"menuType\":\"C\",\"orderNum\":0,\"params\":{},\"parentId\":2037,\"path\":\"ruleDetails\",\"status\":\"0\",\"visible\":\"1\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-29 06:56:01',9),(290,'菜单管理',1,'com.zzyl.web.controller.system.SysMenuController.add()','POST',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"component\":\"nursing/alertRule/index\",\"createBy\":\"admin\",\"icon\":\"nested\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuName\":\"报警规则\",\"menuType\":\"C\",\"orderNum\":1,\"params\":{},\"parentId\":2037,\"path\":\"alertRule\",\"status\":\"0\",\"visible\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-29 06:56:48',8),(291,'菜单管理',1,'com.zzyl.web.controller.system.SysMenuController.add()','POST',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"component\":\"nursing/alertData/index\",\"createBy\":\"admin\",\"icon\":\"skill\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuName\":\"报警数据\",\"menuType\":\"C\",\"orderNum\":2,\"params\":{},\"parentId\":2037,\"path\":\"alertData\",\"status\":\"0\",\"visible\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-29 06:57:25',30),(292,'菜单管理',2,'com.zzyl.web.controller.system.SysMenuController.edit()','PUT',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"component\":\"nursing/device/index\",\"createTime\":\"2024-08-29 06:54:54\",\"icon\":\"tool\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2044,\"menuName\":\"设备管理\",\"menuType\":\"C\",\"orderNum\":0,\"params\":{},\"parentId\":2037,\"path\":\"device\",\"perms\":\"\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-29 07:13:42',11),(293,'菜单管理',2,'com.zzyl.web.controller.system.SysMenuController.edit()','PUT',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"component\":\"nursing/contract/index\",\"createTime\":\"2024-08-23 13:13:55\",\"icon\":\"documentation\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2029,\"menuName\":\"合同\",\"menuType\":\"C\",\"orderNum\":1,\"params\":{},\"parentId\":2019,\"path\":\"contract\",\"perms\":\"nursing:contract:list\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-29 07:35:27',9),(294,'护理项目',1,'com.zzyl.nursing.controller.NursingProjectController.add()','POST',1,'admin','研发部门','/serve/project','127.0.0.1','内网IP','{\"createBy\":\"1\",\"createTime\":\"2024-08-29 16:47:36\",\"id\":1825787069131255811,\"image\":\"https://itheim.oss-cn-beijing.aliyuncs.com/2b6c0e57-feda-4029-8cbb-99181674f474.png\",\"name\":\"修剪指甲\",\"orderNo\":1,\"params\":{},\"price\":10,\"status\":1,\"unit\":\"次\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-29 08:46:32',38),(295,'护理项目',1,'com.zzyl.nursing.controller.NursingProjectController.add()','POST',1,'admin','研发部门','/serve/project','127.0.0.1','内网IP','{\"createBy\":\"1\",\"createTime\":\"2024-08-29 16:51:49\",\"id\":1,\"image\":\"https://itheim.oss-cn-beijing.aliyuncs.com/b6631465-1684-41fe-8ccd-0b027cb91e90.png\",\"name\":\"修剪指甲\",\"nursingRequirement\":\"无\",\"orderNo\":1,\"params\":{},\"price\":10,\"status\":1,\"unit\":\"次\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-29 08:50:45',9),(296,'护理项目',1,'com.zzyl.nursing.controller.NursingProjectController.add()','POST',1,'admin','研发部门','/serve/project','127.0.0.1','内网IP','{\"createBy\":\"1\",\"createTime\":\"2024-08-29 16:52:26\",\"id\":2,\"image\":\"https://itheim.oss-cn-beijing.aliyuncs.com/41fc58d3-0627-4fa9-8459-906599aa1efa.png\",\"name\":\"衣物清洁\",\"nursingRequirement\":\"无\",\"orderNo\":1,\"params\":{},\"price\":5,\"status\":1,\"unit\":\"件\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-29 08:51:21',6),(297,'护理项目',1,'com.zzyl.nursing.controller.NursingProjectController.add()','POST',1,'admin','研发部门','/serve/project','127.0.0.1','内网IP','{\"createBy\":\"1\",\"createTime\":\"2024-08-29 16:52:51\",\"id\":3,\"image\":\"https://itheim.oss-cn-beijing.aliyuncs.com/e611fcc9-dc45-49ac-abeb-f2ea99c2cffc.png\",\"name\":\"整理床铺\",\"nursingRequirement\":\"无\",\"orderNo\":1,\"params\":{},\"price\":15,\"status\":1,\"unit\":\"次\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-29 08:51:46',8),(298,'护理项目',1,'com.zzyl.nursing.controller.NursingProjectController.add()','POST',1,'admin','研发部门','/serve/project','127.0.0.1','内网IP','{\"createBy\":\"1\",\"createTime\":\"2024-08-29 16:53:29\",\"id\":4,\"image\":\"https://itheim.oss-cn-beijing.aliyuncs.com/d91ba642-88e5-4c3d-8e50-a681ae3300e5.png\",\"name\":\"助餐\",\"nursingRequirement\":\"无\",\"orderNo\":1,\"params\":{},\"price\":15,\"status\":1,\"unit\":\"餐\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-29 08:52:24',6),(299,'护理项目',1,'com.zzyl.nursing.controller.NursingProjectController.add()','POST',1,'admin','研发部门','/serve/project','127.0.0.1','内网IP','{\"createBy\":\"1\",\"createTime\":\"2024-08-29 16:53:51\",\"id\":5,\"image\":\"https://itheim.oss-cn-beijing.aliyuncs.com/125df948-7646-4fce-b322-1db0a84856e7.png\",\"name\":\"助浴\",\"nursingRequirement\":\"无\",\"orderNo\":1,\"params\":{},\"price\":40,\"status\":1,\"unit\":\"次\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-29 08:52:46',11),(300,'护理项目',1,'com.zzyl.nursing.controller.NursingProjectController.add()','POST',1,'admin','研发部门','/serve/project','127.0.0.1','内网IP','{\"createBy\":\"1\",\"createTime\":\"2024-08-29 16:54:21\",\"id\":6,\"image\":\"https://itheim.oss-cn-beijing.aliyuncs.com/a38883fc-870b-40ff-a256-54ce2fc17af9.png\",\"name\":\"洗头\",\"nursingRequirement\":\"无\",\"orderNo\":1,\"params\":{},\"price\":20,\"status\":1,\"unit\":\"次\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-29 08:53:17',6),(301,'护理项目',1,'com.zzyl.nursing.controller.NursingProjectController.add()','POST',1,'admin','研发部门','/serve/project','127.0.0.1','内网IP','{\"createBy\":\"1\",\"createTime\":\"2024-08-29 16:54:45\",\"id\":7,\"image\":\"https://itheim.oss-cn-beijing.aliyuncs.com/95b0ad37-5d61-4ec2-a961-d6fb691a18f0.png\",\"name\":\"洗脸\",\"nursingRequirement\":\"无\",\"orderNo\":1,\"params\":{},\"price\":15,\"status\":1,\"unit\":\"次\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-29 08:53:40',6),(302,'护理项目',1,'com.zzyl.nursing.controller.NursingProjectController.add()','POST',1,'admin','研发部门','/serve/project','127.0.0.1','内网IP','{\"createBy\":\"1\",\"createTime\":\"2024-08-29 16:55:08\",\"id\":8,\"image\":\"https://itheim.oss-cn-beijing.aliyuncs.com/8437eb2d-3ea5-4eee-9d78-017bc8b3a66e.png\",\"name\":\"洗脚\",\"nursingRequirement\":\"无\",\"orderNo\":1,\"params\":{},\"price\":20,\"status\":1,\"unit\":\"次\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-29 08:54:03',7),(303,'护理项目',1,'com.zzyl.nursing.controller.NursingProjectController.add()','POST',1,'admin','研发部门','/serve/project','127.0.0.1','内网IP','{\"createBy\":\"1\",\"createTime\":\"2024-08-29 16:55:36\",\"id\":9,\"image\":\"https://itheim.oss-cn-beijing.aliyuncs.com/dc004cc2-688c-4d22-8fbc-8e923219a2bd.png\",\"name\":\"心理咨询\",\"nursingRequirement\":\"无\",\"orderNo\":1,\"params\":{},\"price\":80,\"status\":1,\"unit\":\"小时\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-29 08:54:32',6),(304,'护理计划',2,'com.zzyl.nursing.controller.NursingPlanController.edit()','PUT',1,'admin','研发部门','/nursing/plan','127.0.0.1','内网IP','{\"id\":134,\"status\":1}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-29 08:54:51',72),(305,'护理计划',1,'com.zzyl.nursing.controller.NursingPlanController.add()','POST',1,'admin','研发部门','/nursing/plan','127.0.0.1','内网IP','{\"planName\":\"3号护理计划\",\"projectPlans\":[{\"executeCycle\":2,\"executeFrequency\":1,\"executeTime\":\"16:55:58\",\"params\":{},\"projectId\":1},{\"executeCycle\":0,\"executeFrequency\":1,\"executeTime\":\"16:56:09\",\"params\":{},\"projectId\":5},{\"executeCycle\":0,\"executeFrequency\":1,\"executeTime\":\"08:00:00\",\"params\":{},\"projectId\":4}],\"sortNo\":1,\"status\":1}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-29 08:55:34',22),(306,'护理等级',2,'com.zzyl.nursing.controller.NursingLevelController.edit()','PUT',1,'admin','研发部门','/nursing/level','127.0.0.1','内网IP','{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000,\"id\":77,\"lplanId\":133,\"name\":\"1号护理计划\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2024-08-29 16:57:05\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-29 08:56:00',11),(307,'护理等级',2,'com.zzyl.nursing.controller.NursingLevelController.edit()','PUT',1,'admin','研发部门','/nursing/level','127.0.0.1','内网IP','{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2024-08-29 16:57:23\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-29 08:56:18',7),(308,'护理等级',1,'com.zzyl.nursing.controller.NursingLevelController.add()','POST',1,'admin','研发部门','/nursing/level','127.0.0.1','内网IP','{\"createBy\":\"1\",\"createTime\":\"2024-08-29 16:57:59\",\"description\":\"无\",\"fee\":3000,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-29 08:56:55',9),(309,'代码生成',3,'com.zzyl.generator.controller.GenController.remove()','DELETE',1,'admin','研发部门','/tool/gen/8,9,14,15','127.0.0.1','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-30 06:29:55',38),(310,'代码生成',6,'com.zzyl.generator.controller.GenController.importTableSave()','POST',1,'admin','研发部门','/tool/gen/importTable','127.0.0.1','内网IP','{\"tables\":\"health_assessment\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-30 06:38:33',286),(311,'代码生成',2,'com.zzyl.generator.controller.GenController.editSave()','PUT',1,'admin','研发部门','/tool/gen','127.0.0.1','内网IP','{\"businessName\":\"healthAssessment\",\"className\":\"HealthAssessment\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键\",\"columnId\":226,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-30 06:38:32\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":16,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"ElderName\",\"columnComment\":\"老人姓名\",\"columnId\":227,\"columnName\":\"elder_name\",\"columnType\":\"varchar(255)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-30 06:38:33\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"elderName\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":false,\"sort\":2,\"superColumn\":false,\"tableId\":16,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"IdCard\",\"columnComment\":\"身份证号\",\"columnId\":228,\"columnName\":\"id_card\",\"columnType\":\"varchar(255)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-30 06:38:33\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"idCard\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":false,\"sort\":3,\"superColumn\":false,\"tableId\":16,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"BirthDate\",\"columnComment\":\"出生日期\",\"columnId\":229,\"columnName\":\"birth_date\",\"columnType\":\"datetime\",\"createBy\":\"admin\",\"createTime\":\"2024-08-30 06:38:33\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"datetime\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\"','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-30 06:40:25',156),(312,'代码生成',8,'com.zzyl.generator.controller.GenController.batchGenCode()','GET',1,'admin','研发部门','/tool/gen/batchGenCode','127.0.0.1','内网IP','{\"tables\":\"health_assessment\"}','',0,'','2024-08-30 06:40:42',149),(313,'健康评估',1,'com.zzyl.nursing.controller.HealthAssessmentController.add()','POST',1,'admin','研发部门','/nursing/healthAssessment','127.0.0.1','内网IP','{\"elderName\":\"李爱过\",\"idCard\":\"130123196712131234\",\"physicalExamInstitution\":\"黑马程序员\",\"physicalReportUrl\":\"https://itheim.oss-cn-beijing.aliyuncs.com/dc6314d8-0b68-414b-8825-053794004f39.pdf\"}','{\"msg\":\"操作成功\",\"code\":200,\"data\":5}',0,'','2024-08-30 07:14:57',85205),(314,'健康评估',1,'com.zzyl.nursing.controller.HealthAssessmentController.add()','POST',1,'admin','研发部门','/nursing/healthAssessment','127.0.0.1','内网IP','{\"elderName\":\"李天龙\",\"idCard\":\"123123194912191235\",\"physicalExamInstitution\":\"黑马\",\"physicalReportUrl\":\"https://itheim.oss-cn-beijing.aliyuncs.com/e6f72807-b17f-4f9b-98c3-71f21a7809fe.pdf\"}','',1,'Request failed: Model ERNIE-4.0-8K-Latest is not supported for chat','2024-08-30 08:09:45',96),(315,'健康评估',1,'com.zzyl.nursing.controller.HealthAssessmentController.add()','POST',1,'admin','研发部门','/nursing/healthAssessment','127.0.0.1','内网IP','{\"elderName\":\"张芳\",\"idCard\":\"123123194908011235\",\"physicalExamInstitution\":\"黑马\",\"physicalReportUrl\":\"https://itheim.oss-cn-beijing.aliyuncs.com/83aac1e0-e375-4ea0-a7fa-e6ad54c89f67.pdf\"}','',1,'Text \'2023.10.10\' could not be parsed at index 4','2024-08-30 08:19:50',119210),(316,'健康评估',1,'com.zzyl.nursing.controller.HealthAssessmentController.add()','POST',1,'admin','研发部门','/nursing/healthAssessment','127.0.0.1','内网IP','{\"elderName\":\"张芳\",\"idCard\":\"123192194912151235\",\"physicalExamInstitution\":\"黑马\",\"physicalReportUrl\":\"https://itheim.oss-cn-beijing.aliyuncs.com/0e5b16c3-8ee0-4adb-b0a6-9cc83863ed3a.pdf\"}','',1,'Text \'2023.10.10\' could not be parsed at index 4','2024-08-30 08:28:44',114957),(317,'健康评估',1,'com.zzyl.nursing.controller.HealthAssessmentController.add()','POST',1,'admin','研发部门','/nursing/healthAssessment','127.0.0.1','内网IP','{\"elderName\":\"张芳\",\"idCard\":\"112123194904081235\",\"physicalExamInstitution\":\"黑马\",\"physicalReportUrl\":\"https://itheim.oss-cn-beijing.aliyuncs.com/3ba497a8-01dc-4e37-80aa-1f0015d2f045.pdf\"}','{\"msg\":\"操作成功\",\"code\":200,\"data\":6}',0,'','2024-08-30 08:58:18',124963),(318,'健康评估',1,'com.zzyl.nursing.controller.HealthAssessmentController.add()','POST',1,'admin','研发部门','/nursing/healthAssessment','127.0.0.1','内网IP','{\"elderName\":\"李天龙\",\"idCard\":\"132123195212190912\",\"physicalExamInstitution\":\"黑马\",\"physicalReportUrl\":\"https://itheim.oss-cn-beijing.aliyuncs.com/29e42721-91f4-4df9-bc7d-d10e7b2f8a95.pdf\"}','',1,'Request failed with api error: {\"error_code\":17,\"error_msg\":\"Open api daily request limit reached\"}','2024-08-30 09:09:47',326),(319,'字典类型',1,'com.zzyl.web.controller.system.SysDictTypeController.add()','POST',1,'admin','研发部门','/system/dict/type','127.0.0.1','内网IP','{\"createBy\":\"admin\",\"dictName\":\"健康评估-入住状态\",\"dictType\":\"admission_status\",\"params\":{},\"status\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-31 03:19:57',24),(320,'字典数据',1,'com.zzyl.web.controller.system.SysDictDataController.add()','POST',1,'admin','研发部门','/system/dict/data','127.0.0.1','内网IP','{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"已入住\",\"dictSort\":0,\"dictType\":\"admission_status\",\"dictValue\":\"0\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-31 03:20:26',13),(321,'字典数据',1,'com.zzyl.web.controller.system.SysDictDataController.add()','POST',1,'admin','研发部门','/system/dict/data','127.0.0.1','内网IP','{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"未入住\",\"dictSort\":0,\"dictType\":\"admission_status\",\"dictValue\":\"1\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-08-31 03:20:35',10),(322,'健康评估',1,'com.zzyl.nursing.controller.HealthAssessmentController.add()','POST',1,'admin','研发部门','/nursing/healthAssessment','127.0.0.1','内网IP','{\"elderName\":\"张三\",\"idCard\":\"130123196712131239\",\"physicalExamInstitution\":\"黑马体检\",\"physicalReportUrl\":\"https://itheim.oss-cn-beijing.aliyuncs.com/c4564cc2-ece8-4337-9c3b-95f76eda3ba4.pdf\"}','',1,'Request failed with api error: {\"error_code\":17,\"error_msg\":\"Open api daily request limit reached\"}','2024-08-31 03:44:12',322),(323,'健康评估',1,'com.zzyl.nursing.controller.HealthAssessmentController.add()','POST',1,'admin','研发部门','/nursing/healthAssessment','127.0.0.1','内网IP','{\"elderName\":\"张三\",\"idCard\":\"130123196712131234\",\"physicalExamInstitution\":\"黑马体检\",\"physicalReportUrl\":\"https://itheim.oss-cn-beijing.aliyuncs.com/142b3c36-6b30-4286-beeb-1d77f53ed306.pdf\"}','{\"msg\":\"操作成功\",\"code\":200,\"data\":7}',0,'','2024-08-31 03:48:56',114376),(324,'健康评估',1,'com.zzyl.nursing.controller.HealthAssessmentController.add()','POST',1,'admin','研发部门','/nursing/healthAssessment','127.0.0.1','内网IP','{\"elderName\":\"罗架构\",\"idCard\":\"132123196012161267\",\"physicalExamInstitution\":\"黑马体检\",\"physicalReportUrl\":\"https://itheim.oss-cn-beijing.aliyuncs.com/1fabebdf-7358-4ac6-8c55-e621b6a410a6.pdf\"}','{\"msg\":\"操作成功\",\"code\":200,\"data\":8}',0,'','2024-09-01 03:20:49',85938),(325,'健康评估',1,'com.zzyl.nursing.controller.HealthAssessmentController.add()','POST',1,'admin','研发部门','/nursing/healthAssessment','127.0.0.1','内网IP','{\"elderName\":\"李天龙\",\"idCard\":\"132123196006121234\",\"physicalExamInstitution\":\"黑马体检\",\"physicalReportUrl\":\"https://itheim.oss-cn-beijing.aliyuncs.com/7b6df8e2-95ce-4df8-b60f-97e1272f6045.pdf\"}','{\"msg\":\"操作成功\",\"code\":200,\"data\":9}',0,'','2024-09-01 11:47:51',90471),(326,'代码生成',6,'com.zzyl.generator.controller.GenController.importTableSave()','POST',1,'admin','研发部门','/tool/gen/importTable','127.0.0.1','内网IP','{\"tables\":\"family_member\"}','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-09-02 11:38:49',111),(327,'代码生成',2,'com.zzyl.generator.controller.GenController.editSave()','PUT',1,'admin','研发部门','/tool/gen','127.0.0.1','内网IP','{\"businessName\":\"member\",\"className\":\"FamilyMember\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键\",\"columnId\":251,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-09-02 11:38:49\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":17,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"Phone\",\"columnComment\":\"手机号\",\"columnId\":252,\"columnName\":\"phone\",\"columnType\":\"varchar(20)\",\"createBy\":\"admin\",\"createTime\":\"2024-09-02 11:38:49\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"phone\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":17,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"Name\",\"columnComment\":\"名称\",\"columnId\":253,\"columnName\":\"name\",\"columnType\":\"varchar(100)\",\"createBy\":\"admin\",\"createTime\":\"2024-09-02 11:38:49\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"name\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":false,\"sort\":3,\"superColumn\":false,\"tableId\":17,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"Avatar\",\"columnComment\":\"头像\",\"columnId\":254,\"columnName\":\"avatar\",\"columnType\":\"varchar(255)\",\"createBy\":\"admin\",\"createTime\":\"2024-09-02 11:38:49\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"avatar\",\"javaTyp','{\"msg\":\"操作成功\",\"code\":200}',0,'','2024-09-02 11:39:28',81),(328,'代码生成',8,'com.zzyl.generator.controller.GenController.batchGenCode()','GET',1,'admin','研发部门','/tool/gen/batchGenCode','127.0.0.1','内网IP','{\"tables\":\"family_member\"}','',0,'','2024-09-02 11:39:37',238),(329,'设备',2,'com.zzyl.nursing.controller.DeviceController.edit()','PUT',1,'admin','研发部门','/nursing/device','172.16.43.100','内网IP','{\"bindingLocation\":\"6\",\"deviceDescription\":\"1,4,6\",\"deviceName\":\"xinzengshebei00\",\"id\":202,\"iotId\":\"GDgIaMVb0qzhg2mc9ufTj0rk00\",\"locationType\":1,\"nickname\":\"新增设备001\",\"params\":{},\"physicalLocationType\":2,\"productKey\":\"j0rk0xgSbjY\",\"remark\":\"1楼,104,104-2\",\"updateBy\":\"1\",\"updateTime\":\"2024-09-12 19:00:39\"}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-09-12 19:00:39',257),(330,'报警规则',1,'com.zzyl.nursing.controller.AlertRuleController.add()','POST',1,'admin','研发部门','/nursing/alertRule','172.16.43.100','内网IP','{\"alertDataType\":0,\"alertEffectivePeriod\":\"00:00:00~23:59:59\",\"alertRuleName\":\"水电费第三方\",\"alertSilentPeriod\":5,\"createBy\":\"1\",\"createTime\":\"2024-09-12 19:05:16\",\"deviceName\":\"watch_08\",\"duration\":1,\"functionId\":\"BatteryPercentage\",\"functionName\":\"用电量\",\"id\":52,\"iotId\":\"TGI9pd72wDbEMvAElvYWj0rk00\",\"moduleId\":\"-1\",\"moduleName\":\"默认模块\",\"operator\":\">=\",\"params\":{},\"productKey\":\"j0rk0xgSbjY\",\"productName\":\"健康定位报警手表\",\"remark\":\"5\",\"status\":1,\"value\":60.0}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-09-12 19:05:16',11),(331,'报警规则',3,'com.zzyl.nursing.controller.AlertRuleController.remove()','DELETE',1,'admin','研发部门','/nursing/alertRule/41','172.16.43.100','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-09-12 19:05:59',7),(332,'报警规则',3,'com.zzyl.nursing.controller.AlertRuleController.remove()','DELETE',1,'admin','研发部门','/nursing/alertRule/40','172.16.43.100','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-09-12 19:06:01',3),(333,'报警规则',3,'com.zzyl.nursing.controller.AlertRuleController.remove()','DELETE',1,'admin','研发部门','/nursing/alertRule/39','172.16.43.100','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-09-12 19:06:04',4),(334,'报警规则',3,'com.zzyl.nursing.controller.AlertRuleController.remove()','DELETE',1,'admin','研发部门','/nursing/alertRule/38','172.16.43.100','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-09-12 19:06:06',3),(335,'报警规则',3,'com.zzyl.nursing.controller.AlertRuleController.remove()','DELETE',1,'admin','研发部门','/nursing/alertRule/36','172.16.43.100','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-09-12 19:06:08',4),(336,'报警规则',3,'com.zzyl.nursing.controller.AlertRuleController.remove()','DELETE',1,'admin','研发部门','/nursing/alertRule/35','172.16.43.100','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-09-12 19:06:10',4),(337,'报警规则',3,'com.zzyl.nursing.controller.AlertRuleController.remove()','DELETE',1,'admin','研发部门','/nursing/alertRule/34','172.16.43.100','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-09-12 19:06:13',3),(338,'报警规则',3,'com.zzyl.nursing.controller.AlertRuleController.remove()','DELETE',1,'admin','研发部门','/nursing/alertRule/33','172.16.43.100','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-09-12 19:06:15',3),(339,'报警规则',3,'com.zzyl.nursing.controller.AlertRuleController.remove()','DELETE',1,'admin','研发部门','/nursing/alertRule/32','172.16.43.100','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-09-12 19:06:18',4),(340,'报警规则',3,'com.zzyl.nursing.controller.AlertRuleController.remove()','DELETE',1,'admin','研发部门','/nursing/alertRule/31','172.16.43.100','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-09-12 19:06:20',4),(341,'报警规则',3,'com.zzyl.nursing.controller.AlertRuleController.remove()','DELETE',1,'admin','研发部门','/nursing/alertRule/29','172.16.43.100','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-09-12 19:06:22',4),(342,'报警规则',3,'com.zzyl.nursing.controller.AlertRuleController.remove()','DELETE',1,'admin','研发部门','/nursing/alertRule/30','172.16.43.100','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-09-12 19:06:24',4),(343,'报警规则',3,'com.zzyl.nursing.controller.AlertRuleController.remove()','DELETE',1,'admin','研发部门','/nursing/alertRule/27','172.16.43.100','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-09-12 19:06:26',3),(344,'报警规则',3,'com.zzyl.nursing.controller.AlertRuleController.remove()','DELETE',1,'admin','研发部门','/nursing/alertRule/42','172.16.43.100','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-09-12 19:06:28',7),(345,'报警规则',3,'com.zzyl.nursing.controller.AlertRuleController.remove()','DELETE',1,'admin','研发部门','/nursing/alertRule/43','172.16.43.100','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-09-12 19:06:30',3),(346,'报警规则',3,'com.zzyl.nursing.controller.AlertRuleController.remove()','DELETE',1,'admin','研发部门','/nursing/alertRule/44','172.16.43.100','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-09-12 19:06:39',3),(347,'报警规则',3,'com.zzyl.nursing.controller.AlertRuleController.remove()','DELETE',1,'admin','研发部门','/nursing/alertRule/45','172.16.43.100','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-09-12 19:06:42',3),(348,'报警规则',3,'com.zzyl.nursing.controller.AlertRuleController.remove()','DELETE',1,'admin','研发部门','/nursing/alertRule/47','172.16.43.100','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-09-12 19:06:44',3),(349,'报警规则',3,'com.zzyl.nursing.controller.AlertRuleController.remove()','DELETE',1,'admin','研发部门','/nursing/alertRule/48','172.16.43.100','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-09-12 19:06:46',3),(350,'报警规则',3,'com.zzyl.nursing.controller.AlertRuleController.remove()','DELETE',1,'admin','研发部门','/nursing/alertRule/49','172.16.43.100','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-09-12 19:06:48',3),(351,'设备',2,'com.zzyl.nursing.controller.DeviceController.edit()','PUT',1,'admin','研发部门','/nursing/device','172.16.43.100','内网IP','{\"bindingLocation\":\"1\",\"deviceDescription\":\"1,1,1\",\"deviceName\":\"xzsb001\",\"id\":203,\"iotId\":\"lN27S46N5PArvueMvht1j0rk00\",\"locationType\":1,\"nickname\":\"新增设备001\",\"params\":{},\"physicalLocationType\":2,\"productKey\":\"j0rk0xgSbjY\",\"remark\":\"1楼,101,101-1\",\"updateBy\":\"1\",\"updateTime\":\"2024-09-12 19:15:36\"}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-09-12 19:15:37',182),(352,'设备',2,'com.zzyl.nursing.controller.DeviceController.edit()','PUT',1,'admin','研发部门','/nursing/device','172.16.43.100','内网IP','{\"bindingLocation\":\"328\",\"deviceName\":\"xzsb001\",\"id\":203,\"iotId\":\"lN27S46N5PArvueMvht1j0rk00\",\"locationType\":0,\"nickname\":\"新增设备001\",\"params\":{},\"physicalLocationType\":-1,\"productKey\":\"j0rk0xgSbjY\",\"remark\":\"老李头儿\",\"updateBy\":\"1\",\"updateTime\":\"2024-09-12 19:16:14\"}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-09-12 19:16:14',289),(353,'设备',2,'com.zzyl.nursing.controller.DeviceController.edit()','PUT',1,'admin','研发部门','/nursing/device','172.16.43.100','内网IP','{\"bindingLocation\":\"328\",\"deviceName\":\"xzsb001\",\"id\":203,\"iotId\":\"lN27S46N5PArvueMvht1j0rk00\",\"locationType\":0,\"nickname\":\"新增设备002\",\"params\":{},\"physicalLocationType\":-1,\"productKey\":\"j0rk0xgSbjY\",\"remark\":\"老李头儿\",\"updateBy\":\"1\",\"updateTime\":\"2024-09-12 19:16:35\"}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-09-12 19:16:35',367),(354,'菜单管理',3,'com.zzyl.web.controller.system.SysMenuController.remove()','DELETE',1,'admin','研发部门','/system/menu/2034','127.0.0.1','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-09-12 14:41:12',17),(355,'菜单管理',3,'com.zzyl.web.controller.system.SysMenuController.remove()','DELETE',1,'admin','研发部门','/system/menu/2033','127.0.0.1','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-09-12 14:41:14',12),(356,'菜单管理',3,'com.zzyl.web.controller.system.SysMenuController.remove()','DELETE',1,'admin','研发部门','/system/menu/2032','127.0.0.1','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-09-12 14:41:17',14),(357,'菜单管理',3,'com.zzyl.web.controller.system.SysMenuController.remove()','DELETE',1,'admin','研发部门','/system/menu/2031','127.0.0.1','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-09-12 14:41:20',12),(358,'菜单管理',3,'com.zzyl.web.controller.system.SysMenuController.remove()','DELETE',1,'admin','研发部门','/system/menu/2030','127.0.0.1','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-09-12 14:41:23',11),(359,'菜单管理',3,'com.zzyl.web.controller.system.SysMenuController.remove()','DELETE',1,'admin','研发部门','/system/menu/2029','127.0.0.1','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-09-12 14:41:28',12),(360,'房型',1,'com.zzyl.nursing.controller.RoomTypeController.add()','POST',1,'admin','研发部门','/elder/roomType','127.0.0.1','内网IP','{\"bedCount\":10,\"createBy\":\"1\",\"createTime\":\"2024-09-12 22:52:35\",\"id\":116,\"name\":\"标准双人间\",\"params\":{},\"photo\":\"https://itheim.oss-cn-beijing.aliyuncs.com/91c4a814-efd5-4093-a5ac-963b41047019.png\",\"price\":1500,\"remark\":\"123\",\"status\":0}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-09-12 14:52:35',34),(361,'房型',2,'com.zzyl.nursing.controller.RoomTypeController.edit()','PUT',1,'admin','研发部门','/elder/roomType','127.0.0.1','内网IP','{\"id\":116,\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2024-09-12 22:55:10\"}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-09-12 14:55:10',18),(362,'菜单管理',2,'com.zzyl.web.controller.system.SysMenuController.edit()','PUT',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"component\":\"serve/nursingLevel/index\",\"createTime\":\"2024-08-14 08:29:05\",\"icon\":\"guide\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2007,\"menuName\":\"护理等级\",\"menuType\":\"C\",\"orderNum\":1,\"params\":{},\"parentId\":2000,\"path\":\"nursingLevel\",\"perms\":\"serve:level:list\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-10-03 10:45:44',50),(363,'菜单管理',2,'com.zzyl.web.controller.system.SysMenuController.edit()','PUT',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"component\":\"serve/level/index\",\"createTime\":\"2024-08-14 08:29:05\",\"icon\":\"guide\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2007,\"menuName\":\"护理等级\",\"menuType\":\"C\",\"orderNum\":1,\"params\":{},\"parentId\":2000,\"path\":\"nursingLevel\",\"perms\":\"serve:level:list\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-10-03 10:46:33',20),(364,'菜单管理',2,'com.zzyl.web.controller.system.SysMenuController.edit()','PUT',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"component\":\"\",\"createTime\":\"2024-08-14 08:29:05\",\"icon\":\"#\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2008,\"menuName\":\"护理等级查询\",\"menuType\":\"F\",\"orderNum\":1,\"params\":{},\"parentId\":2007,\"path\":\"#\",\"perms\":\"serve:level:query\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-10-03 10:47:20',13),(365,'菜单管理',2,'com.zzyl.web.controller.system.SysMenuController.edit()','PUT',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"component\":\"\",\"createTime\":\"2024-08-14 08:29:05\",\"icon\":\"#\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2009,\"menuName\":\"护理等级新增\",\"menuType\":\"F\",\"orderNum\":2,\"params\":{},\"parentId\":2007,\"path\":\"#\",\"perms\":\"serve:level:add\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-10-03 10:47:27',18),(366,'菜单管理',2,'com.zzyl.web.controller.system.SysMenuController.edit()','PUT',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"component\":\"\",\"createTime\":\"2024-08-14 08:29:05\",\"icon\":\"#\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2010,\"menuName\":\"护理等级修改\",\"menuType\":\"F\",\"orderNum\":3,\"params\":{},\"parentId\":2007,\"path\":\"#\",\"perms\":\"serve:level:edit\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-10-03 10:47:32',15),(367,'菜单管理',2,'com.zzyl.web.controller.system.SysMenuController.edit()','PUT',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"component\":\"\",\"createTime\":\"2024-08-14 08:29:05\",\"icon\":\"#\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2011,\"menuName\":\"护理等级删除\",\"menuType\":\"F\",\"orderNum\":4,\"params\":{},\"parentId\":2007,\"path\":\"#\",\"perms\":\"serve:level:remove\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-10-03 10:47:37',16),(368,'菜单管理',2,'com.zzyl.web.controller.system.SysMenuController.edit()','PUT',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"component\":\"\",\"createTime\":\"2024-08-14 08:29:05\",\"icon\":\"#\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2012,\"menuName\":\"护理等级导出\",\"menuType\":\"F\",\"orderNum\":5,\"params\":{},\"parentId\":2007,\"path\":\"#\",\"perms\":\"serve:level:export\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-10-03 10:47:42',13),(369,'菜单管理',2,'com.zzyl.web.controller.system.SysMenuController.edit()','PUT',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"component\":\"serve/plan/index\",\"createTime\":\"2024-08-14 08:29:10\",\"icon\":\"druid\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2013,\"menuName\":\"护理计划\",\"menuType\":\"C\",\"orderNum\":1,\"params\":{},\"parentId\":2000,\"path\":\"plan\",\"perms\":\"serve:plan:list\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-10-03 10:48:07',12),(370,'菜单管理',2,'com.zzyl.web.controller.system.SysMenuController.edit()','PUT',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"component\":\"serve/arrange/details\",\"createTime\":\"2024-08-29 06:53:37\",\"icon\":\"#\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2043,\"menuName\":\"任务安排详情\",\"menuType\":\"C\",\"orderNum\":1,\"params\":{},\"parentId\":2000,\"path\":\"arrangeDetails\",\"perms\":\"\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"1\"}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-10-03 10:48:50',15),(371,'菜单管理',2,'com.zzyl.web.controller.system.SysMenuController.edit()','PUT',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"component\":\"serve/oldPeople/index\",\"createTime\":\"2024-08-29 06:52:12\",\"icon\":\"peoples\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2041,\"menuName\":\"负责老人\",\"menuType\":\"C\",\"orderNum\":4,\"params\":{},\"parentId\":2000,\"path\":\"oldPeople\",\"perms\":\"\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-10-03 10:48:56',14),(372,'菜单管理',2,'com.zzyl.web.controller.system.SysMenuController.edit()','PUT',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"component\":\"serve/arrange/index\",\"createTime\":\"2024-08-29 06:53:06\",\"icon\":\"redis-list\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2042,\"menuName\":\"任务安排\",\"menuType\":\"C\",\"orderNum\":5,\"params\":{},\"parentId\":2000,\"path\":\"arrange\",\"perms\":\"\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-10-03 10:49:01',21),(373,'菜单管理',2,'com.zzyl.web.controller.system.SysMenuController.edit()','PUT',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"component\":\"serve/level/index\",\"createTime\":\"2024-08-14 08:29:05\",\"icon\":\"guide\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2007,\"menuName\":\"护理等级\",\"menuType\":\"C\",\"orderNum\":1,\"params\":{},\"parentId\":2000,\"path\":\"level\",\"perms\":\"serve:level:list\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-10-03 10:49:43',14),(374,'菜单管理',2,'com.zzyl.web.controller.system.SysMenuController.edit()','PUT',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"component\":\"serve/plan/index\",\"createTime\":\"2024-08-14 08:29:10\",\"icon\":\"druid\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2013,\"menuName\":\"护理计划\",\"menuType\":\"C\",\"orderNum\":1,\"params\":{},\"parentId\":2000,\"path\":\"plan\",\"perms\":\"serve:plan:list\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-10-03 10:49:50',19),(375,'菜单管理',2,'com.zzyl.web.controller.system.SysMenuController.edit()','PUT',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"component\":\"serve/level/index\",\"createTime\":\"2024-08-14 08:29:05\",\"icon\":\"guide\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2007,\"menuName\":\"护理等级\",\"menuType\":\"C\",\"orderNum\":1,\"params\":{},\"parentId\":2000,\"path\":\"level\",\"perms\":\"serve:level:list\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-10-03 10:49:54',12),(376,'护理计划',2,'com.zzyl.serve.controller.NursingPlanController.edit()','PUT',1,'admin','研发部门','/serve/plan','127.0.0.1','内网IP','{\"id\":134,\"planName\":\"2号护理计划\",\"projectPlans\":[{\"createBy\":\"1\",\"createTime\":\"2024-10-03 22:50:56\",\"executeCycle\":0,\"executeFrequency\":1,\"executeTime\":\"19:28:45\",\"id\":1738,\"params\":{},\"planId\":134,\"projectId\":1}],\"sortNo\":1,\"status\":1}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-10-03 14:50:59',157),(377,'房间',1,'com.zzyl.nursing.controller.RoomController.add()','POST',1,'admin','研发部门','/elder/room','127.0.0.1','内网IP','{\"code\":\"110\",\"createBy\":\"1\",\"createTime\":\"2024-10-03 23:39:54\",\"floorId\":1,\"id\":88,\"params\":{},\"sort\":1,\"typeName\":\"豪华单人间\"}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-10-03 15:39:57',54),(378,'房型',2,'com.zzyl.nursing.controller.RoomTypeController.edit()','PUT',1,'admin','研发部门','/elder/roomType','127.0.0.1','内网IP','{\"bedCount\":0,\"createBy\":\"1671403256519078153\",\"createTime\":\"2023-09-26 15:57:50\",\"id\":1,\"introduction\":\"宽敞舒适的套房,配备独立卫生间和基本生活设施,满足独自居住的需求,提供私密性和舒适度\",\"name\":\"单人套房\",\"params\":{},\"photo\":\"https://yjy-slwl-oss.oss-cn-hangzhou.aliyuncs.com/e2f1031b-e23e-4379-95d4-ce8fe382f58f.png\",\"price\":4001,\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2024-10-03 23:54:29\"}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-10-03 15:54:32',40),(379,'房型',2,'com.zzyl.nursing.controller.RoomTypeController.edit()','PUT',1,'admin','研发部门','/elder/roomType','127.0.0.1','内网IP','{\"bedCount\":0,\"createBy\":\"1671403256519078153\",\"createTime\":\"2023-09-26 15:57:50\",\"id\":1,\"introduction\":\"宽敞舒适的套房,配备独立卫生间和基本生活设施,满足独自居住的需求,提供私密性和舒适度\",\"name\":\"单人套房\",\"params\":{},\"photo\":\"https://yjy-slwl-oss.oss-cn-hangzhou.aliyuncs.com/e2f1031b-e23e-4379-95d4-ce8fe382f58f.png\",\"price\":4000,\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2024-10-03 23:54:33\"}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-10-03 15:54:37',12),(380,'床位',1,'com.zzyl.nursing.controller.BedController.add()','POST',1,'admin','研发部门','/elder/bed','127.0.0.1','内网IP','{\"bedNumber\":\"111\",\"createBy\":\"1\",\"createTime\":\"2024-10-03 23:54:46\",\"id\":2,\"params\":{},\"roomId\":1,\"sort\":1}',NULL,1,'\r\n### Error updating database. Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'2\' for key \'bed.PRIMARY\'\r\n### The error may exist in com/zzyl/nursing/mapper/BedMapper.java (best guess)\r\n### The error may involve com.zzyl.nursing.mapper.BedMapper.insert-Inline\r\n### The error occurred while setting parameters\r\n### SQL: INSERT INTO bed ( id, bed_number, sort, room_id, create_by, create_time, update_by, update_time ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ? )\r\n### Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'2\' for key \'bed.PRIMARY\'\n; Duplicate entry \'2\' for key \'bed.PRIMARY\'; nested exception is java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'2\' for key \'bed.PRIMARY\'','2024-10-03 15:54:50',168),(381,'床位',1,'com.zzyl.nursing.controller.BedController.add()','POST',1,'admin','研发部门','/elder/bed','127.0.0.1','内网IP','{\"bedNumber\":\"111\",\"createBy\":\"1\",\"createTime\":\"2024-10-03 23:54:53\",\"id\":2,\"params\":{},\"roomId\":1,\"sort\":1}',NULL,1,'\r\n### Error updating database. Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'2\' for key \'bed.PRIMARY\'\r\n### The error may exist in com/zzyl/nursing/mapper/BedMapper.java (best guess)\r\n### The error may involve com.zzyl.nursing.mapper.BedMapper.insert-Inline\r\n### The error occurred while setting parameters\r\n### SQL: INSERT INTO bed ( id, bed_number, sort, room_id, create_by, create_time, update_by, update_time ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ? )\r\n### Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'2\' for key \'bed.PRIMARY\'\n; Duplicate entry \'2\' for key \'bed.PRIMARY\'; nested exception is java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'2\' for key \'bed.PRIMARY\'','2024-10-03 15:54:56',6),(382,'床位',1,'com.zzyl.nursing.controller.BedController.add()','POST',1,'admin','研发部门','/elder/bed','127.0.0.1','内网IP','{\"bedNumber\":\"11111\",\"createBy\":\"1\",\"createTime\":\"2024-10-03 23:55:04\",\"id\":2,\"params\":{},\"roomId\":1,\"sort\":1}',NULL,1,'\r\n### Error updating database. Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'2\' for key \'bed.PRIMARY\'\r\n### The error may exist in com/zzyl/nursing/mapper/BedMapper.java (best guess)\r\n### The error may involve com.zzyl.nursing.mapper.BedMapper.insert-Inline\r\n### The error occurred while setting parameters\r\n### SQL: INSERT INTO bed ( id, bed_number, sort, room_id, create_by, create_time, update_by, update_time ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ? )\r\n### Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'2\' for key \'bed.PRIMARY\'\n; Duplicate entry \'2\' for key \'bed.PRIMARY\'; nested exception is java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'2\' for key \'bed.PRIMARY\'','2024-10-03 15:55:07',5),(383,'床位',1,'com.zzyl.nursing.controller.BedController.add()','POST',1,'admin','研发部门','/elder/bed','127.0.0.1','内网IP','{\"bedNumber\":\"11111\",\"createBy\":\"1\",\"createTime\":\"2024-10-03 23:55:07\",\"id\":2,\"params\":{},\"roomId\":1,\"sort\":2}',NULL,1,'\r\n### Error updating database. Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'2\' for key \'bed.PRIMARY\'\r\n### The error may exist in com/zzyl/nursing/mapper/BedMapper.java (best guess)\r\n### The error may involve com.zzyl.nursing.mapper.BedMapper.insert-Inline\r\n### The error occurred while setting parameters\r\n### SQL: INSERT INTO bed ( id, bed_number, sort, room_id, create_by, create_time, update_by, update_time ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ? )\r\n### Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'2\' for key \'bed.PRIMARY\'\n; Duplicate entry \'2\' for key \'bed.PRIMARY\'; nested exception is java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'2\' for key \'bed.PRIMARY\'','2024-10-03 15:55:10',7),(384,'床位',1,'com.zzyl.nursing.controller.BedController.add()','POST',1,'admin','研发部门','/elder/bed','127.0.0.1','内网IP','{\"bedNumber\":\"1111\",\"createBy\":\"1\",\"createTime\":\"2024-10-04 00:01:30\",\"params\":{},\"roomId\":1,\"sort\":1}',NULL,1,'\r\n### Error updating database. Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'1111\' for key \'bed.bed_number\'\r\n### The error may exist in com/zzyl/nursing/mapper/BedMapper.java (best guess)\r\n### The error may involve com.zzyl.nursing.mapper.BedMapper.insert-Inline\r\n### The error occurred while setting parameters\r\n### SQL: INSERT INTO bed ( bed_number, sort, room_id, create_by, create_time, update_by, update_time ) VALUES ( ?, ?, ?, ?, ?, ?, ? )\r\n### Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'1111\' for key \'bed.bed_number\'\n; Duplicate entry \'1111\' for key \'bed.bed_number\'; nested exception is java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'1111\' for key \'bed.bed_number\'','2024-10-03 16:01:33',11),(385,'楼层',1,'com.zzyl.nursing.controller.FloorController.add()','POST',1,'admin','研发部门','/elder/floor','127.0.0.1','内网IP','{\"code\":1,\"createBy\":\"1\",\"createTime\":\"2024-10-04 00:02:58\",\"id\":413,\"name\":\"13楼\",\"params\":{}}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-10-03 16:03:01',15),(386,'床位',1,'com.zzyl.nursing.controller.BedController.add()','POST',1,'admin','研发部门','/elder/bed','127.0.0.1','内网IP','{\"bedNumber\":\"1201-1\",\"createBy\":\"1\",\"createTime\":\"2024-10-04 00:03:31\",\"id\":200,\"params\":{},\"roomId\":83,\"sort\":1}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-10-03 16:03:34',11),(387,'房间',3,'com.zzyl.nursing.controller.RoomController.remove()','DELETE',1,'admin','研发部门','/elder/room/88','127.0.0.1','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-10-03 16:12:20',112),(388,'代码生成',3,'com.zzyl.generator.controller.GenController.remove()','DELETE',1,'admin','研发部门','/tool/gen/16','127.0.0.1','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-10-06 14:46:26',96),(389,'代码生成',3,'com.zzyl.generator.controller.GenController.remove()','DELETE',1,'admin','研发部门','/tool/gen/17','127.0.0.1','内网IP','{}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-10-06 14:46:28',50),(390,'菜单管理',2,'com.zzyl.web.controller.system.SysMenuController.edit()','PUT',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"component\":\"nursing/arrange/details\",\"createTime\":\"2024-08-29 06:53:37\",\"icon\":\"#\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2043,\"menuName\":\"任务安排详情\",\"menuType\":\"C\",\"orderNum\":1,\"params\":{},\"parentId\":2000,\"path\":\"arrangeDetails\",\"perms\":\"\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"1\"}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-11-03 14:24:57',173),(391,'菜单管理',2,'com.zzyl.web.controller.system.SysMenuController.edit()','PUT',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"component\":\"nursing/oldPeople/index\",\"createTime\":\"2024-08-29 06:52:12\",\"icon\":\"peoples\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2041,\"menuName\":\"负责老人\",\"menuType\":\"C\",\"orderNum\":4,\"params\":{},\"parentId\":2000,\"path\":\"oldPeople\",\"perms\":\"\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-11-03 14:25:05',20),(392,'菜单管理',2,'com.zzyl.web.controller.system.SysMenuController.edit()','PUT',1,'admin','研发部门','/system/menu','127.0.0.1','内网IP','{\"children\":[],\"component\":\"nursing/arrange/index\",\"createTime\":\"2024-08-29 06:53:06\",\"icon\":\"redis-list\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2042,\"menuName\":\"任务安排\",\"menuType\":\"C\",\"orderNum\":5,\"params\":{},\"parentId\":2000,\"path\":\"arrange\",\"perms\":\"\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-11-03 14:25:09',30),(393,'床位',2,'com.zzyl.nursing.controller.BedController.edit()','PUT',1,'admin','研发部门','/elder/bed','127.0.0.1','内网IP','{\"bedNumber\":\"108-1\",\"id\":173,\"params\":{},\"sort\":1,\"updateBy\":\"1\",\"updateTime\":\"2024-11-03 23:31:50\"}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-11-03 15:31:49',20),(394,'床位',3,'com.zzyl.nursing.controller.BedController.remove()','DELETE',1,'admin','研发部门','/elder/bed/188','127.0.0.1','内网IP','[188]','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-11-03 15:32:03',21),(395,'用户管理',2,'com.zzyl.web.controller.system.SysUserController.resetPwd()','PUT',1,'admin','研发部门','/system/user/resetPwd','127.0.0.1','内网IP','{\"admin\":false,\"params\":{},\"updateBy\":\"admin\",\"userId\":101}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-11-03 16:11:29',162),(396,'用户管理',2,'com.zzyl.web.controller.system.SysUserController.resetPwd()','PUT',1,'admin','研发部门','/system/user/resetPwd','127.0.0.1','内网IP','{\"admin\":false,\"params\":{},\"updateBy\":\"admin\",\"userId\":102}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-11-03 16:11:36',176),(397,'用户管理',2,'com.zzyl.web.controller.system.SysUserController.resetPwd()','PUT',1,'admin','研发部门','/system/user/resetPwd','127.0.0.1','内网IP','{\"admin\":false,\"params\":{},\"updateBy\":\"admin\",\"userId\":103}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-11-03 16:11:42',220),(398,'用户管理',2,'com.zzyl.web.controller.system.SysUserController.resetPwd()','PUT',1,'admin','研发部门','/system/user/resetPwd','127.0.0.1','内网IP','{\"admin\":false,\"params\":{},\"updateBy\":\"admin\",\"userId\":104}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-11-03 16:11:47',171),(399,'用户管理',2,'com.zzyl.web.controller.system.SysUserController.resetPwd()','PUT',1,'admin','研发部门','/system/user/resetPwd','127.0.0.1','内网IP','{\"admin\":false,\"params\":{},\"updateBy\":\"admin\",\"userId\":105}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2024-11-03 16:11:57',217),(400,'床位',1,'com.zzyl.nursing.controller.BedController.add()','POST',1,'admin','院长办公室','/elder/bed','127.0.0.1','内网IP','{\"bedNumber\":\"109-2\",\"createBy\":\"1\",\"createTime\":\"2025-01-02 00:37:05\",\"id\":201,\"params\":{},\"roomId\":81,\"sort\":2}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2025-01-01 16:37:05',59),(401,'床位',1,'com.zzyl.nursing.controller.BedController.add()','POST',1,'admin','院长办公室','/elder/bed','127.0.0.1','内网IP','{\"bedNumber\":\"108-2\",\"createBy\":\"1\",\"createTime\":\"2025-01-02 00:37:31\",\"id\":202,\"params\":{},\"roomId\":67,\"sort\":2}','{\"msg\":\"操作成功\",\"code\":200}',0,NULL,'2025-01-01 16:37:31',9); +/*!40000 ALTER TABLE `sys_oper_log` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `sys_post` +-- + +DROP TABLE IF EXISTS `sys_post`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `sys_post` ( + `post_id` bigint NOT NULL AUTO_INCREMENT COMMENT '岗位ID', + `post_code` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '岗位编码', + `post_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '岗位名称', + `post_sort` int NOT NULL COMMENT '显示顺序', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '状态(0正常 1停用)', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '创建者', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '更新者', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`post_id`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='岗位信息表'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `sys_post` +-- + +LOCK TABLES `sys_post` WRITE; +/*!40000 ALTER TABLE `sys_post` DISABLE KEYS */; +INSERT INTO `sys_post` VALUES (1,'ceo','董事长',1,'0','admin','2024-08-14 02:48:23','',NULL,''),(2,'se','项目经理',2,'0','admin','2024-08-14 02:48:23','',NULL,''),(3,'hr','人力资源',3,'0','admin','2024-08-14 02:48:23','',NULL,''),(4,'user','普通员工',4,'0','admin','2024-08-14 02:48:23','',NULL,''); +/*!40000 ALTER TABLE `sys_post` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `sys_role` +-- + +DROP TABLE IF EXISTS `sys_role`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `sys_role` ( + `role_id` bigint NOT NULL AUTO_INCREMENT COMMENT '角色ID', + `role_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '角色名称', + `role_key` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '角色权限字符串', + `role_sort` int NOT NULL COMMENT '显示顺序', + `data_scope` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '1' COMMENT '数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限)', + `menu_check_strictly` tinyint(1) DEFAULT '1' COMMENT '菜单树选择项是否关联显示', + `dept_check_strictly` tinyint(1) DEFAULT '1' COMMENT '部门树选择项是否关联显示', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '角色状态(0正常 1停用)', + `del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '创建者', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '更新者', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`role_id`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=104 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='角色信息表'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `sys_role` +-- + +LOCK TABLES `sys_role` WRITE; +/*!40000 ALTER TABLE `sys_role` DISABLE KEYS */; +INSERT INTO `sys_role` VALUES (1,'超级管理员','admin',1,'1',1,1,'0','0','admin','2024-08-14 02:48:23','',NULL,'超级管理员'),(2,'普通角色','common',2,'2',1,1,'0','0','admin','2024-08-14 02:48:23','admin','2024-10-18 10:38:36','普通角色'),(100,'护理员','nursingUser',3,'1',1,1,'0','0','admin','2024-09-24 17:25:26','admin','2024-10-18 10:38:20',NULL),(101,'维修工','maintainer',4,'1',1,1,'0','0','admin','2024-09-24 17:26:31','admin','2024-10-18 10:38:13',NULL),(102,'客服专员','customerService',5,'1',1,1,'0','0','admin','2024-09-24 17:27:42','admin','2024-10-18 10:38:05',NULL),(103,'院长','SuperAdministrator',6,'1',1,1,'0','0','admin','2024-09-24 17:30:54','admin','2024-10-18 10:37:55',NULL); +/*!40000 ALTER TABLE `sys_role` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `sys_role_dept` +-- + +DROP TABLE IF EXISTS `sys_role_dept`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `sys_role_dept` ( + `role_id` bigint NOT NULL COMMENT '角色ID', + `dept_id` bigint NOT NULL COMMENT '部门ID', + PRIMARY KEY (`role_id`,`dept_id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='角色和部门关联表'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `sys_role_dept` +-- + +LOCK TABLES `sys_role_dept` WRITE; +/*!40000 ALTER TABLE `sys_role_dept` DISABLE KEYS */; +INSERT INTO `sys_role_dept` VALUES (2,100),(2,101),(2,105); +/*!40000 ALTER TABLE `sys_role_dept` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `sys_role_menu` +-- + +DROP TABLE IF EXISTS `sys_role_menu`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `sys_role_menu` ( + `role_id` bigint NOT NULL COMMENT '角色ID', + `menu_id` bigint NOT NULL COMMENT '菜单ID', + PRIMARY KEY (`role_id`,`menu_id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='角色和菜单关联表'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `sys_role_menu` +-- + +LOCK TABLES `sys_role_menu` WRITE; +/*!40000 ALTER TABLE `sys_role_menu` DISABLE KEYS */; +INSERT INTO `sys_role_menu` VALUES (2,1),(2,2),(2,3),(2,100),(2,101),(2,102),(2,103),(2,104),(2,105),(2,106),(2,107),(2,108),(2,109),(2,110),(2,111),(2,112),(2,113),(2,114),(2,115),(2,116),(2,117),(2,500),(2,501),(2,1000),(2,1001),(2,1002),(2,1003),(2,1004),(2,1005),(2,1006),(2,1007),(2,1008),(2,1009),(2,1010),(2,1011),(2,1012),(2,1013),(2,1014),(2,1015),(2,1016),(2,1017),(2,1018),(2,1019),(2,1020),(2,1021),(2,1022),(2,1023),(2,1024),(2,1025),(2,1026),(2,1027),(2,1028),(2,1029),(2,1030),(2,1031),(2,1032),(2,1033),(2,1034),(2,1035),(2,1036),(2,1037),(2,1038),(2,1039),(2,1040),(2,1041),(2,1042),(2,1043),(2,1044),(2,1045),(2,1046),(2,1047),(2,1048),(2,1049),(2,1050),(2,1051),(2,1052),(2,1053),(2,1054),(2,1055),(2,1056),(2,1057),(2,1058),(2,1059),(2,1060),(2,2000),(2,2001),(2,2002),(2,2003),(2,2004),(2,2005),(2,2006),(2,2007),(2,2008),(2,2009),(2,2010),(2,2011),(2,2012),(2,2013),(2,2014),(2,2015),(2,2016),(2,2017),(2,2018),(2,2019),(2,2020),(2,2021),(2,2022),(2,2023),(2,2024),(2,2025),(2,2026),(2,2027),(2,2028),(2,2035),(2,2036),(2,2037),(2,2038),(2,2039),(2,2040),(2,2041),(2,2042),(2,2043),(2,2044),(2,2045),(2,2046),(2,2047),(2,2048),(2,2054),(100,1),(100,2),(100,3),(100,100),(100,101),(100,102),(100,103),(100,104),(100,105),(100,106),(100,107),(100,108),(100,109),(100,110),(100,111),(100,112),(100,113),(100,114),(100,115),(100,116),(100,117),(100,500),(100,501),(100,1000),(100,1001),(100,1002),(100,1003),(100,1004),(100,1005),(100,1006),(100,1007),(100,1008),(100,1009),(100,1010),(100,1011),(100,1012),(100,1013),(100,1014),(100,1015),(100,1016),(100,1017),(100,1018),(100,1019),(100,1020),(100,1021),(100,1022),(100,1023),(100,1024),(100,1025),(100,1026),(100,1027),(100,1028),(100,1029),(100,1030),(100,1031),(100,1032),(100,1033),(100,1034),(100,1035),(100,1036),(100,1037),(100,1038),(100,1039),(100,1040),(100,1041),(100,1042),(100,1043),(100,1044),(100,1045),(100,1046),(100,1047),(100,1048),(100,1049),(100,1050),(100,1051),(100,1052),(100,1053),(100,1054),(100,1055),(100,1056),(100,1057),(100,1058),(100,1059),(100,1060),(100,2000),(100,2001),(100,2002),(100,2003),(100,2004),(100,2005),(100,2006),(100,2007),(100,2008),(100,2009),(100,2010),(100,2011),(100,2012),(100,2013),(100,2014),(100,2015),(100,2016),(100,2017),(100,2018),(100,2019),(100,2020),(100,2021),(100,2022),(100,2023),(100,2024),(100,2025),(100,2026),(100,2027),(100,2028),(100,2035),(100,2036),(100,2037),(100,2038),(100,2039),(100,2040),(100,2041),(100,2042),(100,2043),(100,2044),(100,2045),(100,2046),(100,2047),(100,2048),(100,2054),(101,1),(101,2),(101,3),(101,100),(101,101),(101,102),(101,103),(101,104),(101,105),(101,106),(101,107),(101,108),(101,109),(101,110),(101,111),(101,112),(101,113),(101,114),(101,115),(101,116),(101,117),(101,500),(101,501),(101,1000),(101,1001),(101,1002),(101,1003),(101,1004),(101,1005),(101,1006),(101,1007),(101,1008),(101,1009),(101,1010),(101,1011),(101,1012),(101,1013),(101,1014),(101,1015),(101,1016),(101,1017),(101,1018),(101,1019),(101,1020),(101,1021),(101,1022),(101,1023),(101,1024),(101,1025),(101,1026),(101,1027),(101,1028),(101,1029),(101,1030),(101,1031),(101,1032),(101,1033),(101,1034),(101,1035),(101,1036),(101,1037),(101,1038),(101,1039),(101,1040),(101,1041),(101,1042),(101,1043),(101,1044),(101,1045),(101,1046),(101,1047),(101,1048),(101,1049),(101,1050),(101,1051),(101,1052),(101,1053),(101,1054),(101,1055),(101,1056),(101,1057),(101,1058),(101,1059),(101,1060),(101,2000),(101,2001),(101,2002),(101,2003),(101,2004),(101,2005),(101,2006),(101,2007),(101,2008),(101,2009),(101,2010),(101,2011),(101,2012),(101,2013),(101,2014),(101,2015),(101,2016),(101,2017),(101,2018),(101,2019),(101,2020),(101,2021),(101,2022),(101,2023),(101,2024),(101,2025),(101,2026),(101,2027),(101,2028),(101,2035),(101,2036),(101,2037),(101,2038),(101,2039),(101,2040),(101,2041),(101,2042),(101,2043),(101,2044),(101,2045),(101,2046),(101,2047),(101,2048),(101,2054),(102,1),(102,2),(102,3),(102,100),(102,101),(102,102),(102,103),(102,104),(102,105),(102,106),(102,107),(102,108),(102,109),(102,110),(102,111),(102,112),(102,113),(102,114),(102,115),(102,116),(102,117),(102,500),(102,501),(102,1000),(102,1001),(102,1002),(102,1003),(102,1004),(102,1005),(102,1006),(102,1007),(102,1008),(102,1009),(102,1010),(102,1011),(102,1012),(102,1013),(102,1014),(102,1015),(102,1016),(102,1017),(102,1018),(102,1019),(102,1020),(102,1021),(102,1022),(102,1023),(102,1024),(102,1025),(102,1026),(102,1027),(102,1028),(102,1029),(102,1030),(102,1031),(102,1032),(102,1033),(102,1034),(102,1035),(102,1036),(102,1037),(102,1038),(102,1039),(102,1040),(102,1041),(102,1042),(102,1043),(102,1044),(102,1045),(102,1046),(102,1047),(102,1048),(102,1049),(102,1050),(102,1051),(102,1052),(102,1053),(102,1054),(102,1055),(102,1056),(102,1057),(102,1058),(102,1059),(102,1060),(102,2000),(102,2001),(102,2002),(102,2003),(102,2004),(102,2005),(102,2006),(102,2007),(102,2008),(102,2009),(102,2010),(102,2011),(102,2012),(102,2013),(102,2014),(102,2015),(102,2016),(102,2017),(102,2018),(102,2019),(102,2020),(102,2021),(102,2022),(102,2023),(102,2024),(102,2025),(102,2026),(102,2027),(102,2028),(102,2035),(102,2036),(102,2037),(102,2038),(102,2039),(102,2040),(102,2041),(102,2042),(102,2043),(102,2044),(102,2045),(102,2046),(102,2047),(102,2048),(102,2054),(103,1),(103,2),(103,3),(103,100),(103,101),(103,102),(103,103),(103,104),(103,105),(103,106),(103,107),(103,108),(103,109),(103,110),(103,111),(103,112),(103,113),(103,114),(103,115),(103,116),(103,117),(103,500),(103,501),(103,1000),(103,1001),(103,1002),(103,1003),(103,1004),(103,1005),(103,1006),(103,1007),(103,1008),(103,1009),(103,1010),(103,1011),(103,1012),(103,1013),(103,1014),(103,1015),(103,1016),(103,1017),(103,1018),(103,1019),(103,1020),(103,1021),(103,1022),(103,1023),(103,1024),(103,1025),(103,1026),(103,1027),(103,1028),(103,1029),(103,1030),(103,1031),(103,1032),(103,1033),(103,1034),(103,1035),(103,1036),(103,1037),(103,1038),(103,1039),(103,1040),(103,1041),(103,1042),(103,1043),(103,1044),(103,1045),(103,1046),(103,1047),(103,1048),(103,1049),(103,1050),(103,1051),(103,1052),(103,1053),(103,1054),(103,1055),(103,1056),(103,1057),(103,1058),(103,1059),(103,1060),(103,2000),(103,2001),(103,2002),(103,2003),(103,2004),(103,2005),(103,2006),(103,2007),(103,2008),(103,2009),(103,2010),(103,2011),(103,2012),(103,2013),(103,2014),(103,2015),(103,2016),(103,2017),(103,2018),(103,2019),(103,2020),(103,2021),(103,2022),(103,2023),(103,2024),(103,2025),(103,2026),(103,2027),(103,2028),(103,2035),(103,2036),(103,2037),(103,2038),(103,2039),(103,2040),(103,2041),(103,2042),(103,2043),(103,2044),(103,2045),(103,2046),(103,2047),(103,2048),(103,2054); +/*!40000 ALTER TABLE `sys_role_menu` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `sys_user` +-- + +DROP TABLE IF EXISTS `sys_user`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `sys_user` ( + `user_id` bigint NOT NULL AUTO_INCREMENT COMMENT '用户ID', + `dept_id` bigint DEFAULT NULL COMMENT '部门ID', + `user_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户账号', + `nick_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户昵称', + `user_type` varchar(2) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '00' COMMENT '用户类型(00系统用户)', + `email` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '用户邮箱', + `phonenumber` varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '手机号码', + `sex` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '用户性别(0男 1女 2未知)', + `avatar` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '头像地址', + `password` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '密码', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '帐号状态(0正常 1停用)', + `del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)', + `login_ip` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '最后登录IP', + `login_date` datetime DEFAULT NULL COMMENT '最后登录时间', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '创建者', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '更新者', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`user_id`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=106 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='用户信息表'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `sys_user` +-- + +LOCK TABLES `sys_user` WRITE; +/*!40000 ALTER TABLE `sys_user` DISABLE KEYS */; +INSERT INTO `sys_user` VALUES (1,103,'admin','若依','00','ry@163.com','15888888888','1','','$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2','0','0','127.0.0.1','2024-11-04 00:12:15','admin','2024-08-14 02:48:23','','2024-11-03 16:12:14','管理员'),(2,103,'ry','若依','00','ry@qq.com','15666666666','1','','$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2','0','0','127.0.0.1','2024-08-14 02:48:23','admin','2024-08-14 02:48:23','admin','2024-10-18 10:10:07','测试员'),(100,103,'guotianle','guotianle','00','','18888888888','0','','$2a$10$GhMQGKcwBXW43oekDfuSeuddpnBOXqUqRtLdRvGctnFZU4qRnjluK','0','2','127.0.0.1','2024-10-13 10:11:11','admin','2024-10-13 02:10:30','','2024-10-13 02:11:10',NULL),(101,201,'xiaoqing','小青','00','','','1','','$2a$10$Ggf5yLwf.HKHZdmu36ujNuWuBOMb8UhaHKWP.Q1h39AQCM.4Rp.Li','0','0','127.0.0.1','2024-10-18 18:31:55','admin','2024-10-18 10:12:45','admin','2024-11-03 16:11:29',NULL),(102,201,'xiaobai','小白','00','','','1','','$2a$10$gTuSQuL2gCF7DRAog5CQi.f7X7aO4SE18V2EtDmKvUp0YNZKNw9Ou','0','0','',NULL,'admin','2024-10-18 10:13:12','admin','2024-11-03 16:11:36',NULL),(103,202,'laozhang','老张','00','','','0','','$2a$10$vhgwrN3aGZB9q/lVhmfvDOQmkkB9Lo9B2MQjN2vytASPqmdVlCrlO','0','0','',NULL,'admin','2024-10-18 10:13:41','admin','2024-11-03 16:11:42',NULL),(104,103,'laowang','老王','00','','','0','','$2a$10$78oaYzQz3g8JDZg.g6x31eZZvQj7AzViwUJP47s/zazNEGmGe7tbC','0','0','',NULL,'admin','2024-10-18 10:13:59','admin','2024-11-03 16:11:47',NULL),(105,201,'xuxian','许仙','00','','','1','','$2a$10$8tu/vev69rM8rxAECsO8Qe5WQlFgyRSMEHmlY0jcOLWemHj/1rIvq','0','0','',NULL,'admin','2024-10-19 01:27:15','admin','2024-11-03 16:11:57',NULL); +/*!40000 ALTER TABLE `sys_user` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `sys_user_post` +-- + +DROP TABLE IF EXISTS `sys_user_post`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `sys_user_post` ( + `user_id` bigint NOT NULL COMMENT '用户ID', + `post_id` bigint NOT NULL COMMENT '岗位ID', + PRIMARY KEY (`user_id`,`post_id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='用户与岗位关联表'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `sys_user_post` +-- + +LOCK TABLES `sys_user_post` WRITE; +/*!40000 ALTER TABLE `sys_user_post` DISABLE KEYS */; +INSERT INTO `sys_user_post` VALUES (1,1),(2,2),(101,4),(102,4),(103,4),(104,1),(105,4); +/*!40000 ALTER TABLE `sys_user_post` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `sys_user_role` +-- + +DROP TABLE IF EXISTS `sys_user_role`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `sys_user_role` ( + `user_id` bigint NOT NULL COMMENT '用户ID', + `role_id` bigint NOT NULL COMMENT '角色ID', + PRIMARY KEY (`user_id`,`role_id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='用户和角色关联表'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `sys_user_role` +-- + +LOCK TABLES `sys_user_role` WRITE; +/*!40000 ALTER TABLE `sys_user_role` DISABLE KEYS */; +INSERT INTO `sys_user_role` VALUES (1,1),(2,2),(101,100),(102,100),(103,101),(104,103),(105,100); +/*!40000 ALTER TABLE `sys_user_role` ENABLE KEYS */; +UNLOCK TABLES; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +-- Dump completed on 2025-01-02 1:12:38 diff --git a/sql/dev0302.sql b/sql/dev0302.sql new file mode 100644 index 0000000..488e8e6 --- /dev/null +++ b/sql/dev0302.sql @@ -0,0 +1,2774 @@ +/* + Navicat Premium Data Transfer + + Source Server : zzyl + Source Server Type : MySQL + Source Server Version : 80029 (8.0.29) + Source Host : 192.168.100.168:3306 + Source Schema : zzyl + + Target Server Type : MySQL + Target Server Version : 80029 (8.0.29) + File Encoding : 65001 + + Date: 02/03/2025 10:00:49 +*/ + +CREATE DATABASE IF NOT EXISTS `zzyl`; +USE `zzyl`; + +SET NAMES utf8mb4; +SET FOREIGN_KEY_CHECKS = 0; + +-- ---------------------------- +-- Table structure for bed +-- ---------------------------- +DROP TABLE IF EXISTS `bed`; +CREATE TABLE `bed` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '床位ID', + `bed_number` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '床位编号', + `bed_status` int NULL DEFAULT NULL COMMENT '床位状态: 未入住0, 已入住1 ', + `sort` int NULL DEFAULT NULL COMMENT '床位号', + `room_id` bigint NULL DEFAULT NULL COMMENT '房间ID', + `create_time` datetime NOT NULL COMMENT '创建时间', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `create_by` bigint NULL DEFAULT NULL COMMENT '创建人id', + `update_by` bigint NULL DEFAULT NULL COMMENT '更新人id', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `bed_number`(`bed_number` ASC) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 210 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '床位表' ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of bed +-- ---------------------------- +INSERT INTO `bed` VALUES (1, '101-1', 1, 1, 1, '2023-09-26 17:39:53', '2023-10-05 15:59:24', 1671403256519078138, 1671403256519078164, NULL); +INSERT INTO `bed` VALUES (2, '102-1', 0, 1, 2, '2023-09-26 17:40:01', '2023-10-05 16:00:05', 1671403256519078138, 1671403256519078164, NULL); +INSERT INTO `bed` VALUES (3, '102-2', 0, 2, 2, '2023-09-26 17:40:09', '2023-10-05 15:59:45', 1671403256519078138, 1671403256519078164, NULL); +INSERT INTO `bed` VALUES (4, '103-1', 0, 1, 3, '2023-09-26 17:40:42', '2023-10-05 16:00:21', 1671403256519078138, 1671403256519078164, NULL); +INSERT INTO `bed` VALUES (5, '104-1', 1, 1, 4, '2023-09-26 17:40:49', '2023-09-26 17:45:39', 1671403256519078138, 1671403256519078138, NULL); +INSERT INTO `bed` VALUES (6, '104-2', 1, 2, 4, '2023-09-26 17:40:54', '2023-10-20 23:22:12', 1671403256519078138, 1671403256519078164, NULL); +INSERT INTO `bed` VALUES (7, '105-1', 0, 1, 5, '2023-09-26 17:41:09', '2023-09-26 17:45:52', 1671403256519078138, 1671403256519078138, NULL); +INSERT INTO `bed` VALUES (8, '106-1', 0, 1, 6, '2023-09-26 17:41:16', '2023-09-26 17:45:58', 1671403256519078138, 1671403256519078138, NULL); +INSERT INTO `bed` VALUES (9, '106-2', 0, 2, 6, '2023-09-26 17:41:24', '2023-09-26 17:46:04', 1671403256519078138, 1671403256519078138, NULL); +INSERT INTO `bed` VALUES (10, '107-1', 1, 1, 7, '2023-09-26 17:41:32', '2025-02-26 11:04:21', 1671403256519078138, 1, NULL); +INSERT INTO `bed` VALUES (11, '201-1', 0, 1, 8, '2023-09-26 17:44:53', '2023-10-13 10:40:27', 1671403256519078138, 1671403256519078164, NULL); +INSERT INTO `bed` VALUES (12, '202-1', 0, 1, 9, '2023-09-26 17:46:33', '2023-09-26 17:46:33', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (13, '202-2', 0, 2, 9, '2023-09-26 17:46:47', '2023-09-26 17:46:47', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (14, '203-1', 0, 1, 10, '2023-09-26 18:43:58', '2023-09-26 18:43:58', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (15, '204-1', 0, 1, 11, '2023-09-26 18:44:03', '2023-09-26 18:44:03', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (16, '204-2', 0, 2, 11, '2023-09-26 18:44:12', '2023-09-26 18:44:12', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (18, '205-1', 0, 1, 12, '2023-09-26 18:44:23', '2023-12-20 18:40:07', 1671403256519078138, 1671403256519078138, NULL); +INSERT INTO `bed` VALUES (19, '206-1', 0, 1, 13, '2023-09-26 18:44:36', '2023-12-20 21:43:10', 1671403256519078138, 1671403256519078138, NULL); +INSERT INTO `bed` VALUES (20, '206-2', 0, 2, 13, '2023-09-26 18:44:42', '2023-09-26 18:44:48', 1671403256519078138, 1671403256519078138, NULL); +INSERT INTO `bed` VALUES (21, '207-1', 0, 1, 14, '2023-09-26 18:45:01', '2023-09-26 18:45:01', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (22, '301-2', 0, 1, 15, '2023-09-26 18:45:26', '2023-12-26 19:35:06', 1671403256519078138, 1671403256519078138, NULL); +INSERT INTO `bed` VALUES (23, '302-1', 0, 1, 16, '2023-09-26 18:45:31', '2023-09-26 18:45:31', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (24, '302-3', 0, 2, 16, '2023-09-26 18:45:39', '2023-12-26 19:35:15', 1671403256519078138, 1671403256519078138, NULL); +INSERT INTO `bed` VALUES (25, '303-1', 0, 1, 17, '2023-09-26 18:45:44', '2023-09-26 18:45:44', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (27, '304-1', 0, 1, 18, '2023-09-26 18:45:55', '2023-09-26 18:45:55', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (28, '304-2', 0, 2, 18, '2023-09-26 18:46:04', '2023-09-26 18:46:04', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (29, '305-1', 0, 1, 19, '2023-09-26 18:46:11', '2023-12-21 10:04:47', 1671403256519078138, 1671403256519078138, NULL); +INSERT INTO `bed` VALUES (30, '306-1', 0, 1, 20, '2023-09-26 18:46:16', '2023-09-26 18:46:16', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (31, '306-2', 0, 2, 20, '2023-09-26 18:46:22', '2023-09-26 19:08:50', 1671403256519078138, 1671403256519078138, NULL); +INSERT INTO `bed` VALUES (32, '307-1', 0, 1, 21, '2023-09-26 18:46:29', '2023-09-26 18:46:29', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (33, '401-1', 0, 1, 22, '2023-09-26 18:52:14', '2023-09-26 18:52:14', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (34, '402-1', 0, 1, 23, '2023-09-26 18:52:22', '2023-09-26 18:52:22', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (35, '402-2', 0, 2, 23, '2023-09-26 18:52:35', '2023-09-26 18:52:38', 1671403256519078138, 1671403256519078138, NULL); +INSERT INTO `bed` VALUES (36, '403-1', 0, 1, 24, '2023-09-26 18:52:47', '2023-09-26 18:52:47', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (37, '404-1', 0, 1, 25, '2023-09-26 18:52:54', '2023-09-26 18:52:54', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (38, '404-2', 0, 2, 25, '2023-09-26 18:53:02', '2023-09-26 18:53:10', 1671403256519078138, 1671403256519078138, NULL); +INSERT INTO `bed` VALUES (39, '405-1', 0, 1, 26, '2023-09-26 18:53:18', '2023-09-26 18:53:18', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (40, '406-1', 0, 1, 27, '2023-09-26 18:53:27', '2023-09-26 18:53:27', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (41, '406-2', 0, 2, 27, '2023-09-26 18:53:36', '2023-09-26 18:53:36', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (42, '407-1', 0, 1, 28, '2023-09-26 18:53:44', '2023-09-26 18:53:44', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (43, '501-1', 0, 1, 29, '2023-09-26 18:55:47', '2023-09-26 18:55:47', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (44, '502-1', 0, 1, 31, '2023-09-26 18:55:52', '2023-09-26 18:55:52', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (45, '502-2', 1, 2, 31, '2023-09-26 18:56:02', '2025-02-25 16:23:56', 1671403256519078138, 1, NULL); +INSERT INTO `bed` VALUES (46, '503-1', 0, 1, 32, '2023-09-26 18:56:10', '2023-09-26 18:56:10', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (48, '504-1', 0, 1, 33, '2023-09-26 18:56:26', '2023-09-26 18:56:26', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (49, '504-2', 0, 2, 33, '2023-09-26 18:56:32', '2023-09-26 18:56:32', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (50, '505-1', 0, 1, 34, '2023-09-26 18:56:37', '2023-09-26 18:56:37', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (52, '506-1', 0, 1, 35, '2023-09-26 18:56:49', '2023-09-26 18:56:49', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (53, '506-2', 0, 2, 35, '2023-09-26 18:56:54', '2023-09-26 18:56:54', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (54, '507-1', 0, 1, 36, '2023-09-26 18:57:00', '2023-09-26 18:57:00', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (55, '601-1', 1, 1, 37, '2023-09-26 19:05:11', '2025-02-25 16:45:16', 1671403256519078138, 1, NULL); +INSERT INTO `bed` VALUES (56, '602-1', 0, 1, 38, '2023-09-26 19:05:16', '2023-09-26 19:05:16', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (57, '602-2', 0, 2, 38, '2023-09-26 19:05:24', '2023-09-26 19:05:24', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (58, '603-1', 0, 1, 39, '2023-09-26 19:05:29', '2023-09-26 19:05:29', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (59, '604-1', 0, 1, 40, '2023-09-26 19:05:33', '2023-09-26 19:05:33', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (60, '604-2', 0, 2, 40, '2023-09-26 19:05:38', '2023-09-26 19:05:38', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (61, '605-1', 0, 1, 41, '2023-09-26 19:05:43', '2023-09-26 19:05:43', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (62, '606-1', 0, 1, 42, '2023-09-26 19:05:48', '2023-09-26 19:05:48', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (63, '606-2', 0, 2, 42, '2023-09-26 19:05:54', '2023-09-26 19:05:54', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (64, '607-1', 0, 1, 43, '2023-09-26 19:05:59', '2023-09-26 19:05:59', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (65, '701-1', 0, 1, 44, '2023-09-26 19:06:10', '2023-09-26 19:06:10', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (66, '702-1', 0, 1, 45, '2023-09-26 19:06:14', '2023-09-26 19:06:26', 1671403256519078138, 1671403256519078138, NULL); +INSERT INTO `bed` VALUES (68, '702-2', 0, 2, 45, '2023-09-26 19:06:35', '2023-09-26 19:06:35', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (69, '703-1', 0, 1, 46, '2023-09-26 19:06:41', '2023-09-26 19:06:41', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (70, '704-1', 0, 1, 47, '2023-09-26 19:06:46', '2023-12-20 14:28:22', 1671403256519078138, 1671403256519078138, NULL); +INSERT INTO `bed` VALUES (71, '704-2', 0, 2, 47, '2023-09-26 19:06:52', '2023-09-26 19:06:57', 1671403256519078138, 1671403256519078138, NULL); +INSERT INTO `bed` VALUES (72, '705-1', 0, 1, 48, '2023-09-26 19:07:04', '2023-09-26 19:07:04', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (73, '706-1', 0, 1, 49, '2023-09-26 19:07:10', '2023-09-26 19:07:10', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (74, '706-2', 0, 2, 49, '2023-09-26 19:07:14', '2023-09-26 19:07:19', 1671403256519078138, 1671403256519078138, NULL); +INSERT INTO `bed` VALUES (75, '707-1', 0, 1, 50, '2023-09-26 19:07:25', '2023-09-26 19:07:25', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (76, '801-1', 0, 1, 51, '2023-09-26 19:07:41', '2023-09-26 19:07:41', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (77, '803-1', 0, 1, 53, '2023-09-26 19:07:46', '2023-09-26 19:07:46', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (78, '805-1', 0, 1, 55, '2023-09-26 19:07:51', '2023-09-26 19:07:51', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (79, '807-1', 0, 1, 57, '2023-09-26 19:07:56', '2023-09-26 19:07:56', 1671403256519078138, 1, NULL); +INSERT INTO `bed` VALUES (80, '802-1', 0, 1, 52, '2023-09-26 19:08:04', '2023-09-26 19:08:04', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (81, '801-2', 0, 2, 52, '2023-09-26 19:08:09', '2023-09-26 19:08:09', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (82, '804-1', 0, 1, 54, '2023-09-26 19:08:15', '2023-09-26 19:08:15', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (83, '804-2', 0, 2, 54, '2023-09-26 19:08:22', '2023-09-26 19:08:22', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (84, '806-1', 0, 1, 56, '2023-09-26 19:08:28', '2023-09-26 19:08:28', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (85, '806-2', 0, 2, 56, '2023-09-26 19:08:35', '2023-09-26 19:08:35', 1671403256519078138, 1, NULL); +INSERT INTO `bed` VALUES (170, '101-2', 1, 2, 1, '2023-12-21 11:45:09', '2023-12-21 11:45:09', 1671403256519078138, 1, NULL); +INSERT INTO `bed` VALUES (171, '103-2', 0, 1, 3, '2023-12-23 16:12:34', '2023-12-23 16:22:03', 1671403256519078138, 1671403256519078138, NULL); +INSERT INTO `bed` VALUES (173, '108-1', 0, 1, 67, '2023-12-23 17:59:23', '2024-11-03 23:31:50', 1671403256519078138, 1, NULL); +INSERT INTO `bed` VALUES (177, '1011', 0, 1, 74, '2023-12-26 19:32:07', '2023-12-26 19:32:07', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (178, '101', 0, 1, 74, '2023-12-26 19:32:15', '2023-12-26 19:32:15', 1671403256519078138, NULL, NULL); +INSERT INTO `bed` VALUES (196, '109-01', 0, 1, 81, '2024-07-31 11:29:18', NULL, 1, NULL, NULL); +INSERT INTO `bed` VALUES (200, '1201-1', NULL, 1, 83, '2024-10-04 00:03:31', NULL, 1, NULL, NULL); +INSERT INTO `bed` VALUES (201, '109-2', NULL, 2, 81, '2025-01-02 00:37:05', NULL, 1, NULL, NULL); +INSERT INTO `bed` VALUES (204, '110-1', NULL, 1, 89, '2025-02-24 16:31:06', NULL, 1, NULL, NULL); +INSERT INTO `bed` VALUES (207, '110-2', NULL, 2, 89, '2025-02-24 19:20:22', NULL, 1, NULL, NULL); +INSERT INTO `bed` VALUES (208, '111-1', NULL, 1, 91, '2025-02-24 19:19:24', NULL, 1, NULL, NULL); +INSERT INTO `bed` VALUES (209, '109-3', NULL, 3, 81, '2025-02-24 19:19:50', NULL, 1, NULL, NULL); + +-- ---------------------------- +-- Table structure for check_in +-- ---------------------------- +DROP TABLE IF EXISTS `check_in`; +CREATE TABLE `check_in` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `elder_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '老人姓名', + `elder_id` bigint NOT NULL COMMENT '老人ID', + `id_card_no` char(18) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '身份证号', + `start_date` date NOT NULL COMMENT '入住开始时间', + `end_date` date NULL DEFAULT NULL COMMENT '入住结束时间', + `nursing_level_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '护理等级名称', + `bed_number` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '入住床位', + `status` tinyint NOT NULL DEFAULT 0 COMMENT '状态 (0: 已入住, 1: 已退住)', + `sort_order` int NOT NULL DEFAULT 0 COMMENT '排序编号', + `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间', + `create_by` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '创建人', + `update_by` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '修改人', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of check_in +-- ---------------------------- +INSERT INTO `check_in` VALUES (1, '张三', 325, '132123196712131234', '2024-08-27', '2024-09-30', '测试护理等级', '104-1', 0, 0, '2024-08-27 16:43:20', '2024-08-27 08:43:19', '1', NULL, '[{\"kinship\":\"1\",\"name\":\"13211223322\",\"phone\":\"13211223322\"}]'); +INSERT INTO `check_in` VALUES (2, '李天龙', 326, '132123196712131239', '2024-08-27', '2024-09-30', '1号护理计划', '104-2', 0, 0, '2024-08-27 16:50:09', '2024-08-27 08:50:08', '1', NULL, '[{\"kinship\":\"0\",\"name\":\"李天\",\"phone\":\"13222334439\"}]'); +INSERT INTO `check_in` VALUES (3, '老李', 327, '132123195612132345', '2024-09-12', '2024-10-31', '2号护理等级', '101-2', 0, 0, '2024-09-12 18:51:36', '2024-09-12 18:51:36', '1', NULL, '[{\"kinship\":\"1\",\"name\":\"小李\",\"phone\":\"13212349900\"}]'); +INSERT INTO `check_in` VALUES (4, '老李头儿', 328, '410725196904056698', '2024-09-12', '2024-10-31', '2号护理等级', '101-1', 0, 0, '2024-09-12 19:10:23', '2024-09-12 19:10:23', '1', NULL, '[{\"kinship\":\"0\",\"name\":\"老王\",\"phone\":\"15100000002\"}]'); +INSERT INTO `check_in` VALUES (6, '老刘', 330, '430123196003140736', '2025-02-26', '2025-03-26', '2号护理等级', '502-2', 0, 4, '2025-02-25 16:23:56', '2025-02-25 08:23:56', '1', NULL, '[{\"kinship\":\"0\",\"name\":\"小刘一\",\"phone\":\"15238841235\"},{\"kinship\":\"2\",\"name\":\"小刘二\",\"phone\":\"15238841236\"}]'); +INSERT INTO `check_in` VALUES (7, '光头强', 339, '410231196103140736', '2025-02-27', '2025-03-27', '3号护理等级', '601-1', 0, 7, '2025-02-25 16:45:16', '2025-02-25 08:45:16', '1', NULL, '[{\"kinship\":\"3\",\"name\":\"熊大\",\"phone\":\"13568560836\"},{\"kinship\":\"3\",\"name\":\"熊二\",\"phone\":\"15762073711\"}]'); +INSERT INTO `check_in` VALUES (8, '华机菲', 340, '210102195809225319', '2025-02-27', '2025-03-27', '1号护理等级', '107-1', 0, 1, '2025-02-26 11:04:22', '2025-02-26 03:04:20', '1', NULL, '[{\"kinship\":\"0\",\"name\":\"尤请涵\",\"phone\":\"15209217512\"},{\"kinship\":\"1\",\"name\":\"魏构为\",\"phone\":\"13786573590\"}]'); + +-- ---------------------------- +-- Table structure for check_in_config +-- ---------------------------- +DROP TABLE IF EXISTS `check_in_config`; +CREATE TABLE `check_in_config` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `check_in_id` bigint NOT NULL COMMENT '入住表ID', + `nursing_level_id` bigint NOT NULL COMMENT '护理等级ID', + `nursing_level_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '护理等级名称', + `fee_start_date` date NOT NULL COMMENT '费用开始时间', + `fee_end_date` date NULL DEFAULT NULL COMMENT '费用结束时间', + `deposit` decimal(10, 2) NOT NULL COMMENT '押金(元)', + `nursing_fee` decimal(10, 2) NOT NULL COMMENT '护理费用(元/月)', + `bed_fee` decimal(10, 2) NOT NULL COMMENT '床位费用(元/月)', + `insurance_payment` decimal(10, 2) NOT NULL COMMENT '医保支付(元/月)', + `government_subsidy` decimal(10, 2) NOT NULL COMMENT '政府补贴(元/月)', + `other_fees` decimal(10, 2) NOT NULL COMMENT '其他费用(元/月)', + `sort_order` int NOT NULL DEFAULT 0 COMMENT '排序编号', + `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间', + `create_by` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '创建人', + `update_by` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '修改人', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of check_in_config +-- ---------------------------- +INSERT INTO `check_in_config` VALUES (1, 1, 101, '高级护理', '2024-08-01', NULL, 10000.00, 5000.00, 3000.00, 1000.00, 500.00, 500.00, 1, '2025-02-24 10:14:42', '2025-02-24 10:14:42', 'admin', 'admin', '高级护理费用配置.'); +INSERT INTO `check_in_config` VALUES (2, 2, 102, '标准护理', '2024-08-02', NULL, 5000.00, 3000.00, 2000.00, 500.00, 200.00, 300.00, 2, '2025-02-24 10:14:42', '2025-02-24 10:14:42', 'admin', 'admin', '标准护理费用配置.'); +INSERT INTO `check_in_config` VALUES (3, 3, 103, '初级护理', '2024-08-03', '2024-08-05', 3000.00, 2000.00, 1500.00, 300.00, 100.00, 100.00, 3, '2025-02-24 10:14:42', '2025-02-24 10:14:42', 'admin', 'admin', '初级护理费用配置.'); +INSERT INTO `check_in_config` VALUES (4, 4, 104, '中级护理', '2024-08-04', NULL, 7000.00, 4000.00, 2500.00, 800.00, 300.00, 400.00, 4, '2025-02-24 10:14:42', '2025-02-24 10:14:42', 'admin', 'admin', '中级护理费用配置.'); +INSERT INTO `check_in_config` VALUES (5, 6, 76, '2号护理等级', '2025-02-26', '2025-03-26', 3000.00, 1500.00, 6000.00, 2.00, 3.00, 1.00, 5, '2025-02-25 16:23:56', '2025-02-25 08:23:56', '1', NULL, NULL); +INSERT INTO `check_in_config` VALUES (6, 7, 78, '3号护理等级', '2025-02-26', '2025-03-26', 3000.00, 3200.00, 6000.00, 5.00, 6.00, 4.00, 8, '2025-02-25 16:45:16', '2025-02-25 08:45:16', '1', NULL, NULL); +INSERT INTO `check_in_config` VALUES (7, 8, 77, '1号护理等级', '2025-02-27', '2025-03-27', 3000.00, 2000.00, 4000.00, 8.00, 9.00, 7.00, 2, '2025-02-26 11:04:22', '2025-02-26 03:04:20', '1', NULL, NULL); + +-- ---------------------------- +-- Table structure for contract +-- ---------------------------- +DROP TABLE IF EXISTS `contract`; +CREATE TABLE `contract` ( + `id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `elder_id` int NOT NULL COMMENT '老人ID', + `contract_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '合同名称', + `contract_number` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '合同编号', + `agreement_path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '协议地址(文件路径或URL)', + `third_party_phone` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '丙方手机号', + `third_party_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '丙方姓名', + `elder_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '老人姓名', + `start_date` date NOT NULL COMMENT '开始时间', + `end_date` date NOT NULL COMMENT '结束时间', + `status` tinyint NOT NULL DEFAULT 0 COMMENT '状态 (0: 未生效, 1: 已生效, 2: 已过期, 3: 已失效)', + `sign_date` date NOT NULL COMMENT '签约日期', + `termination_submitter` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '解除提交人', + `termination_date` date NULL DEFAULT NULL COMMENT '解除日期', + `termination_agreement_path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '解除协议地址(文件路径或URL)', + `sort_order` int NOT NULL DEFAULT 0 COMMENT '排序编号', + `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间', + `create_by` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '创建人', + `update_by` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '修改人', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of contract +-- ---------------------------- +INSERT INTO `contract` VALUES (1, 1001, 'Standard Care Agreement', 'SCA-2024-001', '/contracts/SCA-2024-001.pdf', '+8613800000000', '张三', '李四', '2024-08-01', '2025-02-01', 3, '2024-07-31', NULL, NULL, NULL, 1, '2025-02-24 10:14:27', '2025-02-27 19:44:41', 'admin', '0', 'Standard care contract.'); +INSERT INTO `contract` VALUES (2, 1002, 'Extended Care Agreement', 'ECA-2024-002', '/contracts/ECA-2024-002.pdf', '+8613900000000', '王五', '赵六', '2024-08-02', '2025-08-02', 1, '2024-08-01', NULL, NULL, NULL, 2, '2025-02-24 10:14:27', '2025-02-27 19:44:41', 'admin', '0', 'Extended care contract.'); +INSERT INTO `contract` VALUES (3, 1003, 'Temporary Care Agreement', 'TCA-2024-003', '/contracts/TCA-2024-003.pdf', '+8613700000000', '陈七', '周八', '2024-08-03', '2024-08-31', 3, '2024-08-03', NULL, NULL, NULL, 3, '2025-02-24 10:14:27', '2025-02-27 19:44:41', 'admin', '0', 'Temporary care contract.'); +INSERT INTO `contract` VALUES (4, 1004, 'Standard Care Agreement', 'SCA-2024-004', '/contracts/SCA-2024-004.pdf', '+8613600000000', '刘九', '郑十', '2024-08-04', '2025-08-04', 1, '2024-08-04', NULL, NULL, NULL, 4, '2025-02-24 10:14:27', '2025-02-27 19:44:41', 'admin', '0', 'Standard care contract.'); +INSERT INTO `contract` VALUES (5, 339, '光头强入住养老院合同', '202502252027590001', 'https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/25/1c2111abe3b945f5b8d81158a4982769.pdf', '13568560836', '熊大', '光头强', '2025-02-27', '2025-03-27', 1, '2025-02-26', NULL, NULL, NULL, 6, '2025-02-25 16:45:16', '2025-02-27 19:44:41', '1', '0', ''); +INSERT INTO `contract` VALUES (6, 340, '华机菲养老院入住合同', '202502261104210001', 'https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/26/bfd2c934e38f4e63bd528e28cd1c5dcc.pdf', '15209217512', '尤请涵', '华机菲', '2025-02-27', '2025-03-27', 1, '2025-02-26', NULL, NULL, NULL, 0, '2025-02-26 11:04:22', '2025-02-27 19:44:41', '1', '0', ''); + +-- ---------------------------- +-- Table structure for elder +-- ---------------------------- +DROP TABLE IF EXISTS `elder`; +CREATE TABLE `elder` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id', + `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '名称', + `image` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '图片', + `id_card_no` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '身份证号', + `sex` int NULL DEFAULT NULL COMMENT '性别(0:女 1:男)', + `status` int NOT NULL DEFAULT 1 COMMENT '状态(0:禁用,1:启用 2:请假 3:退住中 4入住中 5已退住)', + `phone` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '手机号', + `birthday` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '出生日期', + `address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '家庭住址', + `id_card_national_emblem_img` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '身份证国徽面', + `id_card_portrait_img` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '身份证人像面', + `create_time` datetime NOT NULL COMMENT '创建时间', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `create_by` bigint NULL DEFAULT NULL COMMENT '创建人id', + `update_by` bigint NULL DEFAULT NULL COMMENT '更新人id', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + `bed_number` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '床位编号', + `bed_id` bigint NULL DEFAULT NULL COMMENT '床位id', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `name_id_card_no`(`name` ASC, `id_card_no` ASC) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 341 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '老人表' ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of elder +-- ---------------------------- +INSERT INTO `elder` VALUES (325, '13211223322', 'https://itheim.oss-cn-beijing.aliyuncs.com/1fb24c20-ec99-44b3-8691-766c5508b347.jpg', '132123196712131234', 1, 1, '13211223322', '2024-08-22', '13211223322', 'https://itheim.oss-cn-beijing.aliyuncs.com/b79d8d1e-1015-4d04-83e9-a22d3cc47869.jpg', 'https://itheim.oss-cn-beijing.aliyuncs.com/07ee1b38-b611-4955-8339-fad02a6d7fc6.jpg', '2024-08-27 16:43:20', NULL, 1, NULL, NULL, '104-1', 5); +INSERT INTO `elder` VALUES (326, '李天龙', 'https://itheim.oss-cn-beijing.aliyuncs.com/8aef5eb9-436f-4ece-b68f-34d957d6b050.png', '132123196712131239', 1, 1, '13222334433', '1967-12-13', '北京市昌平区', 'https://itheim.oss-cn-beijing.aliyuncs.com/816d7d6c-d13e-4ec6-9879-68d4f8054935.jpg', 'https://itheim.oss-cn-beijing.aliyuncs.com/f96f4666-c58f-4f69-bf15-8a521788330f.jpg', '2024-08-27 16:50:09', NULL, 1, NULL, NULL, '104-2', 6); +INSERT INTO `elder` VALUES (327, '老李', 'https://itheim.oss-cn-beijing.aliyuncs.com/1510df9e-fca8-4a35-9443-8e4bacad0e03.png', '132123195612132345', 1, 1, '13212349900', '1956-12-13', '北京市昌平区', 'https://itheim.oss-cn-beijing.aliyuncs.com/c265f4da-2197-4cfa-91b8-f627a4875c3c.jpg', 'https://itheim.oss-cn-beijing.aliyuncs.com/08347a75-7e07-49ed-bfad-65a553517c52.jpg', '2024-09-12 18:51:36', NULL, 1, NULL, NULL, '101-2', 170); +INSERT INTO `elder` VALUES (328, '老李头儿', NULL, '410725196904056698', 1, 1, '15100000001', '2023-07-04', '知道人色然', NULL, NULL, '2024-09-12 19:10:23', NULL, 1, NULL, NULL, '101-1', 1); +INSERT INTO `elder` VALUES (330, '老刘', 'https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/25/97fd681b13c8494cb5f3fafbdaa14bf7.png', '430123196003140736', 1, 1, '15723517412', '1960-03-14', '测试一', 'https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/25/363080aada2844ce900d48a8c093cd3d.jpg', 'https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/25/18b0626118214e6ea3043d1cf8a9a69d.jpg', '2025-02-25 16:23:56', NULL, 1, NULL, NULL, '502-2', 45); +INSERT INTO `elder` VALUES (339, '光头强', 'https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/25/ac18ca5f769c404d99cab5b16981c75e.png', '410231196103140736', 1, 1, '15734907312', '1961-03-14', '狗熊岭', 'https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/25/93077f4941ee4a73aab63812f963e24f.jpg', 'https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/25/4f7e4776987b4502a07003eec01da4e8.jpg', '2025-02-25 16:45:16', NULL, 1, NULL, NULL, '601-1', 55); +INSERT INTO `elder` VALUES (340, '华机菲', 'https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/26/2aaca1c4b1cd45b8ab0defd08371ed14.png', '210102195809225319', 0, 1, '13684810037', '1958-09-22', '浙江省杭州市', 'https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/26/bafa6edcae9b4604889ea5f41663cd00.jpg', 'https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/26/9de0074ba1464b05a6aaa84c6b8334cb.jpg', '2025-02-26 11:04:22', NULL, 1, NULL, NULL, '107-1', 10); + +-- ---------------------------- +-- Table structure for floor +-- ---------------------------- +DROP TABLE IF EXISTS `floor`; +CREATE TABLE `floor` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id', + `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '名称', + `code` bigint NULL DEFAULT NULL COMMENT '编号', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `create_by` bigint NULL DEFAULT NULL COMMENT '创建人id', + `update_by` bigint NULL DEFAULT NULL COMMENT '更新人id', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `name`(`name` ASC) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 414 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '楼层表' ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of floor +-- ---------------------------- +INSERT INTO `floor` VALUES (1, '1楼', 11, '2023-09-26 16:10:27', '2024-05-24 17:57:28', 1671403256519078153, 1, NULL); +INSERT INTO `floor` VALUES (2, '2楼', 2, '2023-09-26 17:37:20', '2023-09-26 17:37:20', 1671403256519078138, NULL, NULL); +INSERT INTO `floor` VALUES (3, '3楼', 3, '2023-09-26 17:37:26', '2023-09-26 17:37:26', 1671403256519078138, NULL, NULL); +INSERT INTO `floor` VALUES (4, '4楼', 4, '2023-09-26 17:37:32', '2023-09-26 17:37:32', 1671403256519078138, NULL, NULL); +INSERT INTO `floor` VALUES (5, '5楼', 5, '2023-09-26 17:37:38', '2023-09-26 17:37:38', 1671403256519078138, NULL, NULL); +INSERT INTO `floor` VALUES (6, '6楼', 6, '2023-09-26 17:37:42', '2023-09-26 17:37:59', 1671403256519078138, 1671403256519078138, NULL); +INSERT INTO `floor` VALUES (7, '7楼', 7, '2023-09-26 17:37:47', '2023-09-26 17:37:52', 1671403256519078138, 1671403256519078138, NULL); +INSERT INTO `floor` VALUES (8, '8楼', 8, '2023-09-26 17:38:09', '2023-09-26 17:38:09', 1671403256519078138, NULL, NULL); +INSERT INTO `floor` VALUES (391, '9楼', 8, '2023-12-18 14:53:50', '2023-12-18 14:53:50', 1671403256519078138, NULL, NULL); +INSERT INTO `floor` VALUES (401, '10楼', 9, '2023-12-26 19:29:54', '2023-12-27 10:15:34', 1671403256519078138, 1671403256519078138, NULL); +INSERT INTO `floor` VALUES (406, '12楼', 1, '2024-05-27 14:07:32', '2024-05-27 14:14:46', 1, 1, NULL); + +-- ---------------------------- +-- Table structure for gen_table +-- ---------------------------- +DROP TABLE IF EXISTS `gen_table`; +CREATE TABLE `gen_table` ( + `table_id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号', + `table_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '表名称', + `table_comment` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '表描述', + `sub_table_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '关联子表的表名', + `sub_table_fk_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '子表关联的外键名', + `class_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '实体类名称', + `tpl_category` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT 'crud' COMMENT '使用的模板(crud单表操作 tree树表操作)', + `tpl_web_type` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '前端模板类型(element-ui模版 element-plus模版)', + `package_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '生成包路径', + `module_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '生成模块名', + `business_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '生成业务名', + `function_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '生成功能名', + `function_author` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '生成功能作者', + `gen_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '0' COMMENT '生成代码方式(0zip压缩包 1自定义路径)', + `gen_path` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '/' COMMENT '生成路径(不填默认项目路径)', + `options` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '其它生成选项', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`table_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 24 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '代码生成业务表' ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of gen_table +-- ---------------------------- +INSERT INTO `gen_table` VALUES (18, 'nursing_project_plan', '护理计划和项目关联表', NULL, NULL, 'NursingProjectPlan', 'crud', 'element-plus', 'com.zzyl.nursing', 'nursing', 'projectPlan', '护理计划和项目关联', 'Zhy', '0', '/', '{}', 'admin', '2025-02-24 02:07:11', '', '2025-02-24 02:13:23', NULL); +INSERT INTO `gen_table` VALUES (19, 'check_in', '入住表', NULL, NULL, 'CheckIn', 'crud', 'element-plus', 'com.zzyl.nursing', 'nursing', 'checkIn', '入住表', 'Zhy', '0', '/', '{}', 'admin', '2025-02-25 01:29:23', '', '2025-02-25 01:33:20', NULL); +INSERT INTO `gen_table` VALUES (20, 'check_in_config', '入住配置表', NULL, NULL, 'CheckInConfig', 'crud', 'element-plus', 'com.zzyl.nursing', 'nursing', 'checkInConfig', '入住配置表', 'Zhy', '0', '/', '{}', 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:34:07', NULL); +INSERT INTO `gen_table` VALUES (21, 'contract', '合同表', NULL, NULL, 'Contract', 'crud', 'element-plus', 'com.zzyl.nursing', 'nursing', 'contract', '合同表', 'Zhy', '0', '/', '{}', 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:34:58', NULL); +INSERT INTO `gen_table` VALUES (22, 'elder', '老人表', NULL, NULL, 'Elder', 'crud', 'element-plus', 'com.zzyl.nursing', 'nursing', 'elder', '老人', 'Zhy', '0', '/', '{}', 'admin', '2025-02-25 01:29:45', '', '2025-02-25 01:35:12', NULL); +INSERT INTO `gen_table` VALUES (23, 'health_assessment', '健康评估表', NULL, NULL, 'HealthAssessment', 'crud', 'element-plus', 'com.zzyl.nursing', 'nursing', 'healthAssessment', '健康评估', 'Zhy', '0', '/', '{\"parentMenuId\":0}', 'admin', '2025-02-28 03:38:26', '', '2025-02-28 07:01:08', NULL); + +-- ---------------------------- +-- Table structure for gen_table_column +-- ---------------------------- +DROP TABLE IF EXISTS `gen_table_column`; +CREATE TABLE `gen_table_column` ( + `column_id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号', + `table_id` bigint NULL DEFAULT NULL COMMENT '归属表编号', + `column_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '列名称', + `column_comment` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '列描述', + `column_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '列类型', + `java_type` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'JAVA类型', + `java_field` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'JAVA字段名', + `is_pk` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '是否主键(1是)', + `is_increment` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '是否自增(1是)', + `is_required` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '是否必填(1是)', + `is_insert` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '是否为插入字段(1是)', + `is_edit` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '是否编辑字段(1是)', + `is_list` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '是否列表字段(1是)', + `is_query` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '是否查询字段(1是)', + `query_type` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT 'EQ' COMMENT '查询方式(等于、不等于、大于、小于、范围)', + `html_type` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '显示类型(文本框、文本域、下拉框、复选框、单选框、日期控件)', + `dict_type` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '字典类型', + `sort` int NULL DEFAULT NULL COMMENT '排序', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`column_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 369 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '代码生成业务表字段' ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of gen_table_column +-- ---------------------------- +INSERT INTO `gen_table_column` VALUES (262, 18, 'id', '主键ID', 'int', 'Integer', 'id', '1', '1', '0', '1', NULL, NULL, NULL, 'EQ', 'input', '', 1, 'admin', '2025-02-24 02:07:11', '', '2025-02-24 02:13:23'); +INSERT INTO `gen_table_column` VALUES (263, 18, 'plan_id', '计划id', 'int', 'Long', 'planId', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'input', '', 2, 'admin', '2025-02-24 02:07:11', '', '2025-02-24 02:13:23'); +INSERT INTO `gen_table_column` VALUES (264, 18, 'project_id', '项目id', 'int', 'Long', 'projectId', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'input', '', 3, 'admin', '2025-02-24 02:07:11', '', '2025-02-24 02:13:23'); +INSERT INTO `gen_table_column` VALUES (265, 18, 'execute_time', '计划执行时间', 'varchar(50)', 'String', 'executeTime', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'input', '', 4, 'admin', '2025-02-24 02:07:11', '', '2025-02-24 02:13:23'); +INSERT INTO `gen_table_column` VALUES (266, 18, 'execute_cycle', '执行周期 0 天 1 周 2月', 'int', 'Integer', 'executeCycle', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'input', '', 5, 'admin', '2025-02-24 02:07:11', '', '2025-02-24 02:13:23'); +INSERT INTO `gen_table_column` VALUES (267, 18, 'execute_frequency', '执行频次', 'int', 'Integer', 'executeFrequency', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'input', '', 6, 'admin', '2025-02-24 02:07:11', '', '2025-02-24 02:13:23'); +INSERT INTO `gen_table_column` VALUES (268, 18, 'create_time', '创建时间', 'datetime', 'Date', 'createTime', '0', '0', '1', '1', NULL, NULL, NULL, 'EQ', 'datetime', '', 7, 'admin', '2025-02-24 02:07:11', '', '2025-02-24 02:13:23'); +INSERT INTO `gen_table_column` VALUES (269, 18, 'update_time', '更新时间', 'datetime', 'Date', 'updateTime', '0', '0', '0', '1', '1', NULL, NULL, 'EQ', 'datetime', '', 8, 'admin', '2025-02-24 02:07:11', '', '2025-02-24 02:13:23'); +INSERT INTO `gen_table_column` VALUES (270, 18, 'create_by', '创建人id', 'bigint', 'Long', 'createBy', '0', '0', '0', '1', NULL, NULL, NULL, 'EQ', 'input', '', 9, 'admin', '2025-02-24 02:07:11', '', '2025-02-24 02:13:23'); +INSERT INTO `gen_table_column` VALUES (271, 18, 'update_by', '更新人id', 'bigint', 'Long', 'updateBy', '0', '0', '0', '1', '1', NULL, NULL, 'EQ', 'input', '', 10, 'admin', '2025-02-24 02:07:11', '', '2025-02-24 02:13:23'); +INSERT INTO `gen_table_column` VALUES (272, 18, 'remark', '备注', 'varchar(255)', 'String', 'remark', '0', '0', '0', '1', '1', '1', NULL, 'EQ', 'input', '', 11, 'admin', '2025-02-24 02:07:11', '', '2025-02-24 02:13:23'); +INSERT INTO `gen_table_column` VALUES (273, 19, 'id', '主键ID', 'bigint', 'Long', 'id', '1', '1', '0', '1', NULL, NULL, NULL, 'EQ', 'input', '', 1, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:33:20'); +INSERT INTO `gen_table_column` VALUES (274, 19, 'elder_name', '老人姓名', 'varchar(50)', 'String', 'elderName', '0', '0', '1', '1', '1', '1', '1', 'LIKE', 'input', '', 2, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:33:20'); +INSERT INTO `gen_table_column` VALUES (275, 19, 'elder_id', '老人ID', 'bigint', 'Long', 'elderId', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'input', '', 3, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:33:20'); +INSERT INTO `gen_table_column` VALUES (276, 19, 'id_card_no', '身份证号', 'char(18)', 'String', 'idCardNo', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'input', '', 4, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:33:20'); +INSERT INTO `gen_table_column` VALUES (277, 19, 'start_date', '入住开始时间', 'date', 'LocalDateTime', 'startDate', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'datetime', '', 5, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:33:20'); +INSERT INTO `gen_table_column` VALUES (278, 19, 'end_date', '入住结束时间', 'date', 'LocalDateTime', 'endDate', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 6, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:33:20'); +INSERT INTO `gen_table_column` VALUES (279, 19, 'nursing_level_name', '护理等级名称', 'varchar(50)', 'String', 'nursingLevelName', '0', '0', '1', '1', '1', '1', '1', 'LIKE', 'input', '', 7, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:33:20'); +INSERT INTO `gen_table_column` VALUES (280, 19, 'bed_number', '入住床位', 'varchar(50)', 'String', 'bedNumber', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'input', '', 8, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:33:20'); +INSERT INTO `gen_table_column` VALUES (281, 19, 'status', '状态 (0: 已入住, 1: 已退住)', 'tinyint', 'Integer', 'status', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'radio', '', 9, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:33:20'); +INSERT INTO `gen_table_column` VALUES (282, 19, 'sort_order', '排序编号', 'int', 'Integer', 'sortOrder', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'input', '', 10, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:33:20'); +INSERT INTO `gen_table_column` VALUES (283, 19, 'create_time', '创建时间', 'timestamp', 'LocalDateTime', 'createTime', '0', '0', '1', '1', NULL, NULL, NULL, 'EQ', 'datetime', '', 11, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:33:20'); +INSERT INTO `gen_table_column` VALUES (284, 19, 'update_time', '修改时间', 'timestamp', 'LocalDateTime', 'updateTime', '0', '0', '1', '1', '1', NULL, NULL, 'EQ', 'datetime', '', 12, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:33:20'); +INSERT INTO `gen_table_column` VALUES (285, 19, 'create_by', '创建人', 'varchar(50)', 'String', 'createBy', '0', '0', '1', '1', NULL, NULL, NULL, 'EQ', 'input', '', 13, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:33:20'); +INSERT INTO `gen_table_column` VALUES (286, 19, 'update_by', '修改人', 'varchar(50)', 'String', 'updateBy', '0', '0', '1', '1', '1', NULL, NULL, 'EQ', 'input', '', 14, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:33:20'); +INSERT INTO `gen_table_column` VALUES (287, 19, 'remark', '备注', 'varchar(255)', 'String', 'remark', '0', '0', '0', '1', '1', '1', NULL, 'EQ', 'input', '', 15, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:33:20'); +INSERT INTO `gen_table_column` VALUES (288, 20, 'id', '主键ID', 'bigint', 'Long', 'id', '1', '1', '0', '1', NULL, NULL, NULL, 'EQ', 'input', '', 1, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:34:07'); +INSERT INTO `gen_table_column` VALUES (289, 20, 'check_in_id', '入住表ID', 'bigint', 'Long', 'checkInId', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'input', '', 2, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:34:07'); +INSERT INTO `gen_table_column` VALUES (290, 20, 'nursing_level_id', '护理等级ID', 'bigint', 'Long', 'nursingLevelId', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'input', '', 3, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:34:07'); +INSERT INTO `gen_table_column` VALUES (291, 20, 'nursing_level_name', '护理等级名称', 'varchar(50)', 'String', 'nursingLevelName', '0', '0', '1', '1', '1', '1', '1', 'LIKE', 'input', '', 4, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:34:07'); +INSERT INTO `gen_table_column` VALUES (292, 20, 'fee_start_date', '费用开始时间', 'date', 'LocalDateTime', 'feeStartDate', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'datetime', '', 5, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:34:07'); +INSERT INTO `gen_table_column` VALUES (293, 20, 'fee_end_date', '费用结束时间', 'date', 'LocalDateTime', 'feeEndDate', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 6, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:34:07'); +INSERT INTO `gen_table_column` VALUES (294, 20, 'deposit', '押金(元)', 'decimal(10,2)', 'BigDecimal', 'deposit', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'input', '', 7, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:34:07'); +INSERT INTO `gen_table_column` VALUES (295, 20, 'nursing_fee', '护理费用(元/月)', 'decimal(10,2)', 'BigDecimal', 'nursingFee', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'input', '', 8, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:34:07'); +INSERT INTO `gen_table_column` VALUES (296, 20, 'bed_fee', '床位费用(元/月)', 'decimal(10,2)', 'BigDecimal', 'bedFee', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'input', '', 9, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:34:07'); +INSERT INTO `gen_table_column` VALUES (297, 20, 'insurance_payment', '医保支付(元/月)', 'decimal(10,2)', 'BigDecimal', 'insurancePayment', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'input', '', 10, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:34:07'); +INSERT INTO `gen_table_column` VALUES (298, 20, 'government_subsidy', '政府补贴(元/月)', 'decimal(10,2)', 'BigDecimal', 'governmentSubsidy', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'input', '', 11, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:34:07'); +INSERT INTO `gen_table_column` VALUES (299, 20, 'other_fees', '其他费用(元/月)', 'decimal(10,2)', 'BigDecimal', 'otherFees', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'input', '', 12, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:34:07'); +INSERT INTO `gen_table_column` VALUES (300, 20, 'sort_order', '排序编号', 'int', 'Integer', 'sortOrder', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'input', '', 13, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:34:07'); +INSERT INTO `gen_table_column` VALUES (301, 20, 'create_time', '创建时间', 'timestamp', 'LocalDateTime', 'createTime', '0', '0', '1', '1', NULL, NULL, NULL, 'EQ', 'datetime', '', 14, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:34:07'); +INSERT INTO `gen_table_column` VALUES (302, 20, 'update_time', '修改时间', 'timestamp', 'LocalDateTime', 'updateTime', '0', '0', '1', '1', '1', NULL, NULL, 'EQ', 'datetime', '', 15, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:34:07'); +INSERT INTO `gen_table_column` VALUES (303, 20, 'create_by', '创建人', 'varchar(50)', 'String', 'createBy', '0', '0', '1', '1', NULL, NULL, NULL, 'EQ', 'input', '', 16, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:34:07'); +INSERT INTO `gen_table_column` VALUES (304, 20, 'update_by', '修改人', 'varchar(50)', 'String', 'updateBy', '0', '0', '1', '1', '1', NULL, NULL, 'EQ', 'input', '', 17, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:34:07'); +INSERT INTO `gen_table_column` VALUES (305, 20, 'remark', '备注', 'varchar(255)', 'String', 'remark', '0', '0', '0', '1', '1', '1', NULL, 'EQ', 'input', '', 18, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:34:07'); +INSERT INTO `gen_table_column` VALUES (306, 21, 'id', '主键ID', 'int', 'Integer', 'id', '1', '1', '0', '1', NULL, NULL, NULL, 'EQ', 'input', '', 1, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:34:58'); +INSERT INTO `gen_table_column` VALUES (307, 21, 'elder_id', '老人ID', 'int', 'Integer', 'elderId', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'input', '', 2, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:34:58'); +INSERT INTO `gen_table_column` VALUES (308, 21, 'contract_name', '合同名称', 'varchar(100)', 'String', 'contractName', '0', '0', '1', '1', '1', '1', '1', 'LIKE', 'input', '', 3, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:34:58'); +INSERT INTO `gen_table_column` VALUES (309, 21, 'contract_number', '合同编号', 'varchar(50)', 'String', 'contractNumber', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'input', '', 4, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:34:58'); +INSERT INTO `gen_table_column` VALUES (310, 21, 'agreement_path', '协议地址(文件路径或URL)', 'varchar(255)', 'String', 'agreementPath', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'input', '', 5, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:34:58'); +INSERT INTO `gen_table_column` VALUES (311, 21, 'third_party_phone', '丙方手机号', 'varchar(20)', 'String', 'thirdPartyPhone', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'input', '', 6, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:34:58'); +INSERT INTO `gen_table_column` VALUES (312, 21, 'third_party_name', '丙方姓名', 'varchar(50)', 'String', 'thirdPartyName', '0', '0', '1', '1', '1', '1', '1', 'LIKE', 'input', '', 7, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:34:58'); +INSERT INTO `gen_table_column` VALUES (313, 21, 'elder_name', '老人姓名', 'varchar(50)', 'String', 'elderName', '0', '0', '1', '1', '1', '1', '1', 'LIKE', 'input', '', 8, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:34:58'); +INSERT INTO `gen_table_column` VALUES (314, 21, 'start_date', '开始时间', 'date', 'LocalDateTime', 'startDate', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'datetime', '', 9, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:34:58'); +INSERT INTO `gen_table_column` VALUES (315, 21, 'end_date', '结束时间', 'date', 'LocalDateTime', 'endDate', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'datetime', '', 10, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:34:58'); +INSERT INTO `gen_table_column` VALUES (316, 21, 'status', '状态 (0: 未生效, 1: 已生效, 2: 已过期, 3: 已失效)', 'tinyint', 'Integer', 'status', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'radio', '', 11, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:34:58'); +INSERT INTO `gen_table_column` VALUES (317, 21, 'sign_date', '签约日期', 'date', 'LocalDateTime', 'signDate', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'datetime', '', 12, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:34:58'); +INSERT INTO `gen_table_column` VALUES (318, 21, 'termination_submitter', '解除提交人', 'varchar(50)', 'String', 'terminationSubmitter', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 13, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:34:58'); +INSERT INTO `gen_table_column` VALUES (319, 21, 'termination_date', '解除日期', 'date', 'LocalDateTime', 'terminationDate', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 14, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:34:58'); +INSERT INTO `gen_table_column` VALUES (320, 21, 'termination_agreement_path', '解除协议地址(文件路径或URL)', 'varchar(255)', 'String', 'terminationAgreementPath', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 15, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:34:58'); +INSERT INTO `gen_table_column` VALUES (321, 21, 'sort_order', '排序编号', 'int', 'Integer', 'sortOrder', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'input', '', 16, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:34:58'); +INSERT INTO `gen_table_column` VALUES (322, 21, 'create_time', '创建时间', 'timestamp', 'LocalDateTime', 'createTime', '0', '0', '1', '1', NULL, NULL, NULL, 'EQ', 'datetime', '', 17, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:34:58'); +INSERT INTO `gen_table_column` VALUES (323, 21, 'update_time', '修改时间', 'timestamp', 'LocalDateTime', 'updateTime', '0', '0', '1', '1', '1', NULL, NULL, 'EQ', 'datetime', '', 18, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:34:58'); +INSERT INTO `gen_table_column` VALUES (324, 21, 'create_by', '创建人', 'varchar(50)', 'String', 'createBy', '0', '0', '1', '1', NULL, NULL, NULL, 'EQ', 'input', '', 19, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:34:58'); +INSERT INTO `gen_table_column` VALUES (325, 21, 'update_by', '修改人', 'varchar(50)', 'String', 'updateBy', '0', '0', '1', '1', '1', NULL, NULL, 'EQ', 'input', '', 20, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:34:58'); +INSERT INTO `gen_table_column` VALUES (326, 21, 'remark', '备注', 'varchar(255)', 'String', 'remark', '0', '0', '0', '1', '1', '1', NULL, 'EQ', 'input', '', 21, 'admin', '2025-02-25 01:29:24', '', '2025-02-25 01:34:58'); +INSERT INTO `gen_table_column` VALUES (327, 22, 'id', 'id', 'bigint', 'Long', 'id', '1', '1', '0', '1', NULL, NULL, NULL, 'EQ', 'input', '', 1, 'admin', '2025-02-25 01:29:45', '', '2025-02-25 01:35:12'); +INSERT INTO `gen_table_column` VALUES (328, 22, 'name', '名称', 'varchar(255)', 'String', 'name', '0', '0', '0', '1', '1', '1', '1', 'LIKE', 'input', '', 2, 'admin', '2025-02-25 01:29:45', '', '2025-02-25 01:35:12'); +INSERT INTO `gen_table_column` VALUES (329, 22, 'image', '图片', 'varchar(255)', 'String', 'image', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'imageUpload', '', 3, 'admin', '2025-02-25 01:29:45', '', '2025-02-25 01:35:12'); +INSERT INTO `gen_table_column` VALUES (330, 22, 'id_card_no', '身份证号', 'varchar(20)', 'String', 'idCardNo', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 4, 'admin', '2025-02-25 01:29:45', '', '2025-02-25 01:35:12'); +INSERT INTO `gen_table_column` VALUES (331, 22, 'sex', '性别(0:女 1:男)', 'int', 'Integer', 'sex', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'select', '', 5, 'admin', '2025-02-25 01:29:45', '', '2025-02-25 01:35:12'); +INSERT INTO `gen_table_column` VALUES (332, 22, 'status', '状态(0:禁用,1:启用 2:请假 3:退住中 4入住中 5已退住)', 'int', 'Integer', 'status', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'radio', '', 6, 'admin', '2025-02-25 01:29:45', '', '2025-02-25 01:35:12'); +INSERT INTO `gen_table_column` VALUES (333, 22, 'phone', '手机号', 'varchar(50)', 'String', 'phone', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'input', '', 7, 'admin', '2025-02-25 01:29:45', '', '2025-02-25 01:35:12'); +INSERT INTO `gen_table_column` VALUES (334, 22, 'birthday', '出生日期', 'varchar(50)', 'String', 'birthday', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 8, 'admin', '2025-02-25 01:29:45', '', '2025-02-25 01:35:12'); +INSERT INTO `gen_table_column` VALUES (335, 22, 'address', '家庭住址', 'varchar(255)', 'String', 'address', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 9, 'admin', '2025-02-25 01:29:45', '', '2025-02-25 01:35:12'); +INSERT INTO `gen_table_column` VALUES (336, 22, 'id_card_national_emblem_img', '身份证国徽面', 'varchar(255)', 'String', 'idCardNationalEmblemImg', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 10, 'admin', '2025-02-25 01:29:45', '', '2025-02-25 01:35:12'); +INSERT INTO `gen_table_column` VALUES (337, 22, 'id_card_portrait_img', '身份证人像面', 'varchar(255)', 'String', 'idCardPortraitImg', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 11, 'admin', '2025-02-25 01:29:45', '', '2025-02-25 01:35:12'); +INSERT INTO `gen_table_column` VALUES (338, 22, 'create_time', '创建时间', 'datetime', 'LocalDateTime', 'createTime', '0', '0', '1', '1', NULL, NULL, NULL, 'EQ', 'datetime', '', 12, 'admin', '2025-02-25 01:29:45', '', '2025-02-25 01:35:12'); +INSERT INTO `gen_table_column` VALUES (339, 22, 'update_time', '更新时间', 'datetime', 'LocalDateTime', 'updateTime', '0', '0', '0', '1', '1', NULL, NULL, 'EQ', 'datetime', '', 13, 'admin', '2025-02-25 01:29:45', '', '2025-02-25 01:35:12'); +INSERT INTO `gen_table_column` VALUES (340, 22, 'create_by', '创建人id', 'bigint', 'Long', 'createBy', '0', '0', '0', '1', NULL, NULL, NULL, 'EQ', 'input', '', 14, 'admin', '2025-02-25 01:29:45', '', '2025-02-25 01:35:12'); +INSERT INTO `gen_table_column` VALUES (341, 22, 'update_by', '更新人id', 'bigint', 'Long', 'updateBy', '0', '0', '0', '1', '1', NULL, NULL, 'EQ', 'input', '', 15, 'admin', '2025-02-25 01:29:45', '', '2025-02-25 01:35:12'); +INSERT INTO `gen_table_column` VALUES (342, 22, 'remark', '备注', 'varchar(255)', 'String', 'remark', '0', '0', '0', '1', '1', '1', NULL, 'EQ', 'input', '', 16, 'admin', '2025-02-25 01:29:45', '', '2025-02-25 01:35:12'); +INSERT INTO `gen_table_column` VALUES (343, 22, 'bed_number', '床位编号', 'varchar(20)', 'String', 'bedNumber', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 17, 'admin', '2025-02-25 01:29:45', '', '2025-02-25 01:35:12'); +INSERT INTO `gen_table_column` VALUES (344, 22, 'bed_id', '床位id', 'bigint', 'Long', 'bedId', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 18, 'admin', '2025-02-25 01:29:45', '', '2025-02-25 01:35:12'); +INSERT INTO `gen_table_column` VALUES (345, 23, 'id', '主键', 'bigint', 'Long', 'id', '1', '1', '0', '1', NULL, NULL, NULL, 'EQ', 'input', '', 1, 'admin', '2025-02-28 03:38:26', '', '2025-02-28 07:01:08'); +INSERT INTO `gen_table_column` VALUES (346, 23, 'elder_name', '老人姓名', 'varchar(255)', 'String', 'elderName', '0', '0', '0', '1', '1', '1', '1', 'LIKE', 'input', '', 2, 'admin', '2025-02-28 03:38:26', '', '2025-02-28 07:01:08'); +INSERT INTO `gen_table_column` VALUES (347, 23, 'id_card', '身份证号', 'varchar(255)', 'String', 'idCard', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 3, 'admin', '2025-02-28 03:38:26', '', '2025-02-28 07:01:08'); +INSERT INTO `gen_table_column` VALUES (348, 23, 'birth_date', '出生日期', 'datetime', 'LocalDateTime', 'birthDate', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 4, 'admin', '2025-02-28 03:38:26', '', '2025-02-28 07:01:08'); +INSERT INTO `gen_table_column` VALUES (349, 23, 'age', '年龄', 'int', 'Integer', 'age', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 5, 'admin', '2025-02-28 03:38:26', '', '2025-02-28 07:01:08'); +INSERT INTO `gen_table_column` VALUES (350, 23, 'gender', '性别(0:男,1:女)', 'int', 'Integer', 'gender', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 6, 'admin', '2025-02-28 03:38:26', '', '2025-02-28 07:01:08'); +INSERT INTO `gen_table_column` VALUES (351, 23, 'health_score', '健康评分', 'varchar(255)', 'String', 'healthScore', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 7, 'admin', '2025-02-28 03:38:26', '', '2025-02-28 07:01:08'); +INSERT INTO `gen_table_column` VALUES (352, 23, 'risk_level', '危险等级(健康, 提示, 风险, 危险, 严重危险)', 'varchar(255)', 'String', 'riskLevel', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 8, 'admin', '2025-02-28 03:38:26', '', '2025-02-28 07:01:08'); +INSERT INTO `gen_table_column` VALUES (353, 23, 'suggestion_for_admission', '是否建议入住(0:建议,1:不建议)', 'int', 'Integer', 'suggestionForAdmission', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 9, 'admin', '2025-02-28 03:38:26', '', '2025-02-28 07:01:08'); +INSERT INTO `gen_table_column` VALUES (354, 23, 'nursing_level_name', '推荐护理等级', 'varchar(255)', 'String', 'nursingLevelName', '0', '0', '0', '1', '1', '1', '1', 'LIKE', 'input', '', 10, 'admin', '2025-02-28 03:38:26', '', '2025-02-28 07:01:08'); +INSERT INTO `gen_table_column` VALUES (355, 23, 'admission_status', '入住情况(0:已入住,1:未入住)', 'int', 'Integer', 'admissionStatus', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'radio', '', 11, 'admin', '2025-02-28 03:38:26', '', '2025-02-28 07:01:08'); +INSERT INTO `gen_table_column` VALUES (356, 23, 'total_check_date', '总检日期', 'varchar(64)', 'String', 'totalCheckDate', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 12, 'admin', '2025-02-28 03:38:26', '', '2025-02-28 07:01:08'); +INSERT INTO `gen_table_column` VALUES (357, 23, 'physical_exam_institution', '体检机构', 'varchar(255)', 'String', 'physicalExamInstitution', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 13, 'admin', '2025-02-28 03:38:26', '', '2025-02-28 07:01:08'); +INSERT INTO `gen_table_column` VALUES (358, 23, 'physical_report_url', '体检报告URL链接', 'varchar(255)', 'String', 'physicalReportUrl', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 14, 'admin', '2025-02-28 03:38:26', '', '2025-02-28 07:01:08'); +INSERT INTO `gen_table_column` VALUES (359, 23, 'assessment_time', '评估时间', 'datetime', 'LocalDateTime', 'assessmentTime', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 15, 'admin', '2025-02-28 03:38:26', '', '2025-02-28 07:01:08'); +INSERT INTO `gen_table_column` VALUES (360, 23, 'report_summary', '报告总结', 'text', 'String', 'reportSummary', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'textarea', '', 16, 'admin', '2025-02-28 03:38:26', '', '2025-02-28 07:01:08'); +INSERT INTO `gen_table_column` VALUES (361, 23, 'disease_risk', '疾病风险', 'text', 'String', 'diseaseRisk', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'textarea', '', 17, 'admin', '2025-02-28 03:38:26', '', '2025-02-28 07:01:08'); +INSERT INTO `gen_table_column` VALUES (362, 23, 'abnormal_analysis', '异常分析', 'text', 'String', 'abnormalAnalysis', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'textarea', '', 18, 'admin', '2025-02-28 03:38:26', '', '2025-02-28 07:01:08'); +INSERT INTO `gen_table_column` VALUES (363, 23, 'system_score', '健康系统分值', 'varchar(255)', 'String', 'systemScore', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 19, 'admin', '2025-02-28 03:38:26', '', '2025-02-28 07:01:08'); +INSERT INTO `gen_table_column` VALUES (364, 23, 'create_by', '创建者', 'varchar(255)', 'String', 'createBy', '0', '0', '0', '1', NULL, NULL, NULL, 'EQ', 'input', '', 20, 'admin', '2025-02-28 03:38:26', '', '2025-02-28 07:01:08'); +INSERT INTO `gen_table_column` VALUES (365, 23, 'create_time', '创建时间', 'datetime', 'LocalDateTime', 'createTime', '0', '0', '0', '1', NULL, NULL, NULL, 'EQ', 'datetime', '', 21, 'admin', '2025-02-28 03:38:26', '', '2025-02-28 07:01:08'); +INSERT INTO `gen_table_column` VALUES (366, 23, 'update_by', '更新者', 'varchar(255)', 'String', 'updateBy', '0', '0', '0', '1', '1', NULL, NULL, 'EQ', 'input', '', 22, 'admin', '2025-02-28 03:38:26', '', '2025-02-28 07:01:08'); +INSERT INTO `gen_table_column` VALUES (367, 23, 'update_time', '更新时间', 'datetime', 'LocalDateTime', 'updateTime', '0', '0', '0', '1', '1', NULL, NULL, 'EQ', 'datetime', '', 23, 'admin', '2025-02-28 03:38:26', '', '2025-02-28 07:01:08'); +INSERT INTO `gen_table_column` VALUES (368, 23, 'remark', '备注', 'text', 'String', 'remark', '0', '0', '0', '1', '1', '1', NULL, 'EQ', 'textarea', '', 24, 'admin', '2025-02-28 03:38:26', '', '2025-02-28 07:01:08'); + +-- ---------------------------- +-- Table structure for health_assessment +-- ---------------------------- +DROP TABLE IF EXISTS `health_assessment`; +CREATE TABLE `health_assessment` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键', + `elder_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '老人姓名', + `id_card` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '身份证号', + `birth_date` datetime NULL DEFAULT NULL COMMENT '出生日期', + `age` int NULL DEFAULT NULL COMMENT '年龄', + `gender` int NULL DEFAULT NULL COMMENT '性别(0:男,1:女)', + `health_score` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '健康评分', + `risk_level` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '危险等级(健康, 提示, 风险, 危险, 严重危险)', + `suggestion_for_admission` int NULL DEFAULT NULL COMMENT '是否建议入住(0:建议,1:不建议)', + `nursing_level_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '推荐护理等级', + `admission_status` int NULL DEFAULT NULL COMMENT '入住情况(0:已入住,1:未入住)', + `total_check_date` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '总检日期', + `physical_exam_institution` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '体检机构', + `physical_report_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '体检报告URL链接', + `assessment_time` datetime NULL DEFAULT NULL COMMENT '评估时间', + `report_summary` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '报告总结', + `disease_risk` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '疾病风险', + `abnormal_analysis` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '异常分析', + `system_score` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '健康系统分值', + `create_by` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '创建者', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '更新者', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `remark` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '备注', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '健康评估表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of health_assessment +-- ---------------------------- +INSERT INTO `health_assessment` VALUES (2, '刘爱国', '210102196001267626', '1960-01-26 00:00:00', 64, 0, '80.5', 'caution', 0, '二级护理等级', 1, '2023-10-10', '中州体检', 'https://java110-ai.oss-cn-beijing.aliyuncs.com/2024/10/af59dc76-0c01-4043-9706-b9ed1ec08984.pdf', '2024-10-10 01:07:42', '体检报告中心率、肝脏、胆囊、脾脏、肾脏、前列腺共6项指标提示异常,综合这些临床指标和数据分析:循环系统、消化系统存在隐患,其中循环系统有“中危”风险;消化系统部位有“低危”风险。', '{\"healthy\":60,\"caution\":30,\"risk\":10,\"danger\":0,\"severeDanger\":0}', '[{\"conclusion\":\"心率略快\",\"examinationItem\":\"心率\",\"result\":\"92 次/分\",\"referenceValue\":\"< 140\",\"unit\":\"次/分\",\"interpret\":\"心率稍高于理想范围,可能与情绪、活动或轻度心脏负担有关。\",\"advice\":\"建议心电图检查及定期监测心率,保持情绪稳定,适量运动。\"},{\"conclusion\":\"轻度脂肪肝可能\",\"examinationItem\":\"肝\",\"result\":\"形态大小正常,实质回声略粗糙\",\"referenceValue\":\"-\",\"unit\":\"-\",\"interpret\":\"肝脏实质回声略粗糙,提示可能有轻度脂肪肝,与饮食习惯、生活方式或遗传因素有关。\",\"advice\":\"建议调整饮食结构,减少高脂食物摄入,增加运动,定期检查肝脏情况。\"},{\"conclusion\":\"慢性胆囊炎可能\",\"examinationItem\":\"胆\",\"result\":\"胆囊壁毛糙\",\"referenceValue\":\"-\",\"unit\":\"-\",\"interpret\":\"胆囊壁毛糙,可能表示有慢性胆囊炎,可能与胆囊结石、感染或长期饮食不规律有关。\",\"advice\":\"建议进一步检查胆囊情况,保持规律饮食,避免高脂食物。\"},{\"conclusion\":\"脾轻度增大\",\"examinationItem\":\"脾\",\"result\":\"轻度增大\",\"referenceValue\":\"-\",\"unit\":\"-\",\"interpret\":\"脾脏轻度增大,可能与感染、血液系统疾病或自身免疫性疾病有关。\",\"advice\":\"建议进一步检查脾脏,以确定增大的原因,并采取相应的治疗措施。\"},{\"conclusion\":\"右肾小囊肿可能\",\"examinationItem\":\"肾\",\"result\":\"右肾下极见一大小约 5mm 的无回声区\",\"referenceValue\":\"-\",\"unit\":\"mm\",\"interpret\":\"右肾小囊肿,一般为良性病变,可能与肾小管憩室增多有关。\",\"advice\":\"建议定期监测囊肿大小,若无症状且囊肿不增大,可暂不处理。\"},{\"conclusion\":\"前列腺形态略增大\",\"examinationItem\":\"前列腺\",\"result\":\"形态略增大\",\"referenceValue\":\"-\",\"unit\":\"-\",\"interpret\":\"前列腺形态略增大,可能与前列腺增生有关,是老年男性常见病变。\",\"advice\":\"建议进行PSA检查以排除前列腺肿瘤,并定期检查前列腺情况。\"}]', '{\"breathingSystem\":100,\"digestiveSystem\":85,\"endocrineSystem\":90,\"immuneSystem\":95,\"circulatorySystem\":80,\"urinarySystem\":90,\"motionSystem\":100,\"senseSystem\":90}', '1', '2024-10-10 01:07:42', NULL, NULL, NULL); +INSERT INTO `health_assessment` VALUES (5, '张芳', '410182195309190744', '1953-09-19 00:00:00', 71, 1, '75.0', 'caution', 0, '三级护理等级', 1, '2023.10.10', '传智健康体检中心', 'https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/28/0b3d9d0e75c24c7f8f80585a00f89988.pdf', '2025-02-28 19:16:47', '体检报告中血红蛋白、血压、胆固醇、低密度脂蛋白、右耳听力、双下肢、视力、乙肝表面抗体、脾、右肾共10项指标提示异常。综合这些临床指标和数据分析:循环系统、泌尿系统、免疫系统存在隐患,其中循环系统有“中危”风险;泌尿系统、免疫系统部位有“低危”风险。', '{\"healthy\":60,\"caution\":30,\"risk\":10,\"danger\":0,\"severeDanger\":0}', '[{\"conclusion\":\"双下肢水肿\",\"examinationItem\":\"内科检查\",\"result\":\"双下肢轻微凹陷性水肿\",\"referenceValue\":\"无水肿\",\"unit\":\"-\",\"interpret\":\"双下肢水肿可能与心肾功能异常有关,需要进一步检查以确定具体原因。\",\"advice\":\"建议进行心肾功能检查,根据检查结果采取相应治疗措施。同时,避免长时间站立或久坐,定期抬高下肢以促进血液循环。\"},{\"conclusion\":\"视力下降\",\"examinationItem\":\"眼科检查\",\"result\":\"视力略有下降\",\"referenceValue\":\"正常视力\",\"unit\":\"-\",\"interpret\":\"视力下降可能与年龄、用眼习惯、眼部疾病等因素有关。\",\"advice\":\"建议定期复查视力,配戴合适的老花镜,并注意用眼卫生,避免长时间用眼。\"},{\"conclusion\":\"右耳听力下降\",\"examinationItem\":\"耳鼻喉科检查\",\"result\":\"右耳听力下降\",\"referenceValue\":\"正常听力\",\"unit\":\"-\",\"interpret\":\"听力下降可能与年龄、耳部疾病、噪音暴露等因素有关。\",\"advice\":\"建议耳鼻喉科进一步评估,并根据评估结果采取相应治疗措施。避免长时间暴露于高噪音环境中。\"},{\"conclusion\":\"血压偏高\",\"examinationItem\":\"一般科室检查\",\"result\":\"收缩压 145 mmHg,舒张压 90 mmHg\",\"referenceValue\":\"收缩压 < 140 mmHg,舒张压 < 90 mmHg\",\"unit\":\"mmHg\",\"interpret\":\"血压偏高可能与生活习惯、遗传因素、其他疾病等有关,长期高血压可能增加心脑血管疾病风险。\",\"advice\":\"建议定期监测血压,改善生活习惯(如低盐饮食、适量运动),必要时心内科随访并考虑药物治疗。\"},{\"conclusion\":\"血红蛋白略低\",\"examinationItem\":\"血常规检查\",\"result\":\"血红蛋白 110 g/l\",\"referenceValue\":\"120-160 g/l\",\"unit\":\"g/l\",\"interpret\":\"血红蛋白略低可能与营养不良、贫血等因素有关。\",\"advice\":\"建议增加富含铁质的食物摄入,如红肉、绿叶蔬菜等,并定期进行血常规检查以监测血红蛋白水平。\"},{\"conclusion\":\"胆固醇及低密度脂蛋白略高\",\"examinationItem\":\"生化检查\",\"result\":\"总胆固醇 6.2 mmol/L,低密度脂蛋白 4.0 mmol/L\",\"referenceValue\":\"总胆固醇 2.3-5.7 mmol/L,低密度脂蛋白 2.1-3.1 mmol/L\",\"unit\":\"mmol/L\",\"interpret\":\"胆固醇及低密度脂蛋白略高可能与饮食习惯、遗传因素等有关,长期高水平可能增加心脑血管疾病风险。\",\"advice\":\"建议饮食控制,减少高脂肪食物摄入,增加蔬菜水果摄入,并定期进行生化检查以监测血脂水平。\"},{\"conclusion\":\"乙肝表面抗体阴性\",\"examinationItem\":\"免疫检查\",\"result\":\"乙肝表面抗体 阴性\",\"referenceValue\":\"阳性(接种乙肝疫苗后)\",\"unit\":\"-\",\"interpret\":\"乙肝表面抗体阴性表示未接种过乙肝疫苗或疫苗接种效果不佳,可能增加乙肝病毒感染风险。\",\"advice\":\"建议接种乙肝疫苗以提高抵抗力。\"},{\"conclusion\":\"脾轻度增大\",\"examinationItem\":\"B超检查\",\"result\":\"脾轻度增大\",\"referenceValue\":\"正常大小\",\"unit\":\"-\",\"interpret\":\"脾轻度增大可能与感染、血液系统疾病、自身免疫性疾病等因素有关。\",\"advice\":\"建议进一步检查以确定具体原因,并根据检查结果采取相应治疗措施。\"},{\"conclusion\":\"右肾小囊肿可能\",\"examinationItem\":\"B超检查\",\"result\":\"右肾下极见一大小约 5mm 的无回声区\",\"referenceValue\":\"无囊肿\",\"unit\":\"-\",\"interpret\":\"右肾小囊肿可能是一种良性病变,但需要进一步检查以确定性质。\",\"advice\":\"建议定期进行肾脏B超检查以监测囊肿变化,如有必要,可考虑手术治疗。\"}]', '{\"breathingSystem\":90,\"digestiveSystem\":85,\"endocrineSystem\":90,\"immuneSystem\":80,\"circulatorySystem\":75,\"urinarySystem\":80,\"motionSystem\":90,\"senseSystem\":85}', '1', '2025-02-28 19:16:47', NULL, NULL, NULL); + +-- ---------------------------- +-- Table structure for nursing_elder +-- ---------------------------- +DROP TABLE IF EXISTS `nursing_elder`; +CREATE TABLE `nursing_elder` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id', + `nursing_id` bigint NULL DEFAULT NULL COMMENT '护理员id', + `elder_id` bigint NULL DEFAULT NULL COMMENT '老人id', + `create_time` datetime NOT NULL COMMENT '创建时间', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `create_by` bigint NULL DEFAULT NULL COMMENT '创建人id', + `update_by` bigint NULL DEFAULT NULL COMMENT '更新人id', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `nursing_id`(`nursing_id` ASC, `elder_id` ASC) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '护理员老人关联表' ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of nursing_elder +-- ---------------------------- +INSERT INTO `nursing_elder` VALUES (2, 101, 327, '2025-01-02 01:07:42', NULL, 1, NULL, NULL); +INSERT INTO `nursing_elder` VALUES (3, 102, 327, '2025-01-02 01:07:42', NULL, 1, NULL, NULL); +INSERT INTO `nursing_elder` VALUES (4, 101, 328, '2025-01-02 01:07:42', NULL, 1, NULL, NULL); +INSERT INTO `nursing_elder` VALUES (5, 102, 328, '2025-01-02 01:07:42', NULL, 1, NULL, NULL); +INSERT INTO `nursing_elder` VALUES (6, 101, 325, '2025-01-02 01:07:48', NULL, 1, NULL, NULL); +INSERT INTO `nursing_elder` VALUES (7, 101, 326, '2025-01-02 01:07:48', NULL, 1, NULL, NULL); + +-- ---------------------------- +-- Table structure for nursing_level +-- ---------------------------- +DROP TABLE IF EXISTS `nursing_level`; +CREATE TABLE `nursing_level` ( + `id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '等级名称', + `lplan_id` int NOT NULL COMMENT '护理计划ID', + `fee` decimal(10, 2) NOT NULL COMMENT '护理费用', + `status` tinyint(1) NOT NULL DEFAULT 1 COMMENT '状态(0:禁用,1:启用)', + `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '等级说明', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `create_by` bigint NULL DEFAULT NULL COMMENT '创建人id', + `update_by` bigint NULL DEFAULT NULL COMMENT '更新人id', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + `update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `name`(`name` ASC) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 82 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '护理等级表' ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of nursing_level +-- ---------------------------- +INSERT INTO `nursing_level` VALUES (76, '2号护理等级', 134, 1500.00, 1, '1223', '2024-08-14 16:33:16', NULL, NULL, NULL, '2024-08-29 16:57:23'); +INSERT INTO `nursing_level` VALUES (77, '1号护理等级', 133, 2000.00, 1, '1223', '2024-08-20 11:18:21', NULL, 1, NULL, '2025-02-25 09:42:34'); +INSERT INTO `nursing_level` VALUES (78, '3号护理等级', 135, 3200.00, 1, '无', '2024-08-29 16:58:00', NULL, 1, NULL, '2025-02-25 09:28:51'); +INSERT INTO `nursing_level` VALUES (81, '4号护理等级', 141, 2300.00, 1, '4号护理等级', '2025-02-27 16:24:41', 1, NULL, NULL, '2025-02-27 08:24:39'); + +-- ---------------------------- +-- Table structure for nursing_plan +-- ---------------------------- +DROP TABLE IF EXISTS `nursing_plan`; +CREATE TABLE `nursing_plan` ( + `id` int NOT NULL AUTO_INCREMENT COMMENT '编号', + `sort_no` int NULL DEFAULT NULL COMMENT '排序号', + `plan_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '名称', + `status` tinyint NOT NULL DEFAULT 0 COMMENT '状态 0禁用 1启用', + `create_time` datetime NOT NULL COMMENT '创建时间', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `create_by` bigint NULL DEFAULT NULL COMMENT '创建人id', + `update_by` bigint NULL DEFAULT NULL COMMENT '更新人id', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `plan_name`(`plan_name` ASC) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 148 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '护理计划表' ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of nursing_plan +-- ---------------------------- +INSERT INTO `nursing_plan` VALUES (133, 1, '1号护理计划', 1, '2024-08-19 19:17:31', NULL, NULL, NULL, NULL); +INSERT INTO `nursing_plan` VALUES (134, 1, '2号护理计划', 1, '2024-08-19 19:36:10', NULL, NULL, NULL, NULL); +INSERT INTO `nursing_plan` VALUES (135, 1, '3号护理计划', 0, '2024-08-29 16:56:39', '2025-02-24 13:27:00', NULL, 1, NULL); +INSERT INTO `nursing_plan` VALUES (141, 1, '4号护理计划', 1, '2025-02-24 13:50:52', '2025-02-27 20:24:22', 1, 1, NULL); + +-- ---------------------------- +-- Table structure for nursing_project +-- ---------------------------- +DROP TABLE IF EXISTS `nursing_project`; +CREATE TABLE `nursing_project` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号', + `name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '名称', + `order_no` int NULL DEFAULT NULL COMMENT '排序号', + `unit` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '单位', + `price` decimal(10, 2) NULL DEFAULT NULL COMMENT '价格', + `image` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '图片', + `nursing_requirement` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '护理要求', + `status` int NOT NULL DEFAULT 1 COMMENT '状态(0:禁用,1:启用)', + `create_by` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '创建人', + `update_by` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '更新人', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `name`(`name` ASC) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 10 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '护理项目表' ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of nursing_project +-- ---------------------------- +INSERT INTO `nursing_project` VALUES (1, '修剪指甲', 1, '次', 10.00, 'https://itheim.oss-cn-beijing.aliyuncs.com/b6631465-1684-41fe-8ccd-0b027cb91e90.png', '无', 0, '1', '1', NULL, '2024-08-29 16:51:50', '2025-02-24 10:46:27'); +INSERT INTO `nursing_project` VALUES (2, '衣物清洁', 1, '件', 5.00, 'https://itheim.oss-cn-beijing.aliyuncs.com/41fc58d3-0627-4fa9-8459-906599aa1efa.png', '无', 1, '1', NULL, NULL, '2024-08-29 16:52:27', '2024-08-29 08:51:21'); +INSERT INTO `nursing_project` VALUES (3, '整理床铺', 1, '次', 15.00, 'https://itheim.oss-cn-beijing.aliyuncs.com/e611fcc9-dc45-49ac-abeb-f2ea99c2cffc.png', '无', 1, '1', NULL, NULL, '2024-08-29 16:52:52', '2024-08-29 08:51:46'); +INSERT INTO `nursing_project` VALUES (4, '助餐', 1, '餐', 15.00, 'https://itheim.oss-cn-beijing.aliyuncs.com/d91ba642-88e5-4c3d-8e50-a681ae3300e5.png', '无', 0, '1', '1', NULL, '2024-08-29 16:53:29', '2025-02-24 10:46:25'); +INSERT INTO `nursing_project` VALUES (5, '助浴', 1, '次', 40.00, 'https://itheim.oss-cn-beijing.aliyuncs.com/125df948-7646-4fce-b322-1db0a84856e7.png', '无', 1, '1', NULL, NULL, '2024-08-29 16:53:51', '2024-08-29 08:52:46'); +INSERT INTO `nursing_project` VALUES (6, '洗头', 1, '次', 20.00, 'https://itheim.oss-cn-beijing.aliyuncs.com/a38883fc-870b-40ff-a256-54ce2fc17af9.png', '无', 1, '1', NULL, NULL, '2024-08-29 16:54:22', '2024-08-29 08:53:17'); +INSERT INTO `nursing_project` VALUES (7, '洗脸', 1, '次', 15.00, 'https://itheim.oss-cn-beijing.aliyuncs.com/95b0ad37-5d61-4ec2-a961-d6fb691a18f0.png', '无', 1, '1', NULL, NULL, '2024-08-29 16:54:45', '2024-08-29 08:53:40'); +INSERT INTO `nursing_project` VALUES (8, '洗脚', 1, '次', 20.00, 'https://itheim.oss-cn-beijing.aliyuncs.com/8437eb2d-3ea5-4eee-9d78-017bc8b3a66e.png', '无', 0, '1', '1', NULL, '2024-08-29 16:55:08', '2025-02-24 15:26:17'); +INSERT INTO `nursing_project` VALUES (9, '心理咨询', 1, '小时', 70.00, 'https://itheim.oss-cn-beijing.aliyuncs.com/dc004cc2-688c-4d22-8fbc-8e923219a2bd.png', '无', 1, '1', '1', NULL, '2024-08-29 16:55:37', '2025-02-27 20:23:58'); + +-- ---------------------------- +-- Table structure for nursing_project_plan +-- ---------------------------- +DROP TABLE IF EXISTS `nursing_project_plan`; +CREATE TABLE `nursing_project_plan` ( + `id` int NOT NULL AUTO_INCREMENT, + `plan_id` int NOT NULL COMMENT '计划id', + `project_id` int NOT NULL COMMENT '项目id', + `execute_time` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '计划执行时间', + `execute_cycle` int NOT NULL COMMENT '执行周期 0 天 1 周 2月', + `execute_frequency` int NOT NULL COMMENT '执行频次', + `create_time` datetime NOT NULL COMMENT '创建时间', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `create_by` bigint NULL DEFAULT NULL COMMENT '创建人id', + `update_by` bigint NULL DEFAULT NULL COMMENT '更新人id', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 1760 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '护理计划和项目关联表' ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of nursing_project_plan +-- ---------------------------- +INSERT INTO `nursing_project_plan` VALUES (1736, 133, 87, '19:16:49', 1, 7, '2024-08-19 11:28:43', NULL, NULL, NULL, NULL); +INSERT INTO `nursing_project_plan` VALUES (1737, 133, 85, '19:28:34', 1, 1, '2024-08-19 11:28:43', NULL, NULL, NULL, NULL); +INSERT INTO `nursing_project_plan` VALUES (1742, 134, 1, '19:28:45', 0, 1, '2024-10-03 14:50:59', NULL, NULL, NULL, NULL); +INSERT INTO `nursing_project_plan` VALUES (1758, 141, 5, '13:50:33', 1, 2, '2025-02-27 12:24:21', NULL, NULL, NULL, NULL); +INSERT INTO `nursing_project_plan` VALUES (1759, 141, 2, '18:16:22', 0, 1, '2025-02-27 12:24:21', NULL, NULL, NULL, NULL); + +-- ---------------------------- +-- Table structure for nursing_task +-- ---------------------------- +DROP TABLE IF EXISTS `nursing_task`; +CREATE TABLE `nursing_task` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id', + `nursing_id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '护理员id', + `project_id` int NOT NULL COMMENT '项目id', + `project_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '护理项目名称', + `elder_id` bigint NULL DEFAULT NULL COMMENT '老人id', + `elder_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '老人姓名', + `bed_number` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '床位编号', + `estimated_server_time` datetime NULL DEFAULT NULL COMMENT '预计服务时间', + `real_server_time` datetime NULL DEFAULT NULL COMMENT '实际服务时间', + `mark` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '执行记录', + `cancel_reason` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '取消原因', + `status` int NULL DEFAULT NULL COMMENT '状态 1待执行 2已执行 3已关闭 ', + `task_image` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '执行图片', + `create_time` datetime NOT NULL COMMENT '创建时间', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `create_by` bigint NULL DEFAULT NULL COMMENT '创建人id', + `update_by` bigint NULL DEFAULT NULL COMMENT '更新人id', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '护理任务表' ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of nursing_task +-- ---------------------------- + +-- ---------------------------- +-- Table structure for room +-- ---------------------------- +DROP TABLE IF EXISTS `room`; +CREATE TABLE `room` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '房间编号', + `sort` int NULL DEFAULT NULL COMMENT '排序号', + `type_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '房间类型名称', + `floor_id` bigint NULL DEFAULT NULL COMMENT '楼层id', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `is_deleted` tinyint(1) NULL DEFAULT 0 COMMENT '是否删除', + `create_by` bigint NULL DEFAULT NULL COMMENT '创建人id', + `update_by` bigint NULL DEFAULT NULL COMMENT '更新人id', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `code`(`code` ASC) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 92 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '房间表' ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of room +-- ---------------------------- +INSERT INTO `room` VALUES (1, '101', 1, '豪华单人间', 1, '2023-09-26 17:38:25', '2023-12-23 16:19:55', 0, 1671403256519078138, 1671403256519078138, NULL); +INSERT INTO `room` VALUES (2, '102', 2, '普通双人间', 1, '2023-09-26 17:38:32', '2023-09-26 17:38:32', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (3, '103', 3, '普通单人间', 1, '2023-09-26 17:38:41', '2023-09-26 17:38:41', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (4, '104', 4, '豪华双人间', 1, '2023-09-26 17:38:48', '2023-09-26 17:38:48', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (5, '105', 5, '豪华单人间', 1, '2023-09-26 17:38:55', '2023-09-26 17:38:55', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (6, '106', 6, '双人套房', 1, '2023-09-26 17:39:05', '2023-09-26 17:39:05', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (7, '107', 7, '单人套房', 1, '2023-09-26 17:39:13', '2023-09-26 17:39:13', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (8, '201', 1, '特护房', 2, '2023-09-26 17:42:02', '2023-09-26 17:42:02', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (9, '202', 2, '普通双人间', 2, '2023-09-26 17:42:08', '2023-09-26 17:42:08', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (10, '203', 3, '普通单人间', 2, '2023-09-26 17:42:15', '2023-09-26 17:42:15', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (11, '204', 4, '豪华双人间', 2, '2023-09-26 17:42:22', '2023-09-26 17:42:22', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (12, '205', 5, '豪华单人间', 2, '2023-09-26 17:42:30', '2023-09-26 17:42:30', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (13, '206', 6, '双人套房', 2, '2023-09-26 17:42:41', '2023-09-26 17:42:41', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (14, '207', 7, '单人套房', 2, '2023-09-26 17:42:48', '2023-09-26 17:42:48', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (15, '301', 1, '特护房', 3, '2023-09-26 17:43:54', '2023-09-26 17:43:54', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (16, '302', 2, '普通双人间', 3, '2023-09-26 17:44:01', '2023-09-26 17:44:01', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (17, '303', 3, '普通单人间', 3, '2023-09-26 17:44:09', '2023-09-26 17:44:09', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (18, '304', 4, '豪华双人间', 3, '2023-09-26 17:44:17', '2023-09-26 17:44:17', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (19, '305', 5, '豪华单人间', 3, '2023-09-26 17:44:24', '2023-09-26 17:44:24', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (20, '306', 6, '双人套房', 3, '2023-09-26 17:44:33', '2023-09-26 17:44:33', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (21, '307', 7, '单人套房', 3, '2023-09-26 17:44:42', '2023-09-26 17:44:42', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (22, '401', 1, '特护房', 4, '2023-09-26 18:51:10', '2023-09-26 18:51:10', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (23, '402', 2, '普通双人间', 4, '2023-09-26 18:51:17', '2023-09-26 18:51:17', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (24, '403', 3, '普通单人间', 4, '2023-09-26 18:51:23', '2023-09-26 18:51:23', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (25, '404', 4, '豪华双人间', 4, '2023-09-26 18:51:32', '2023-09-26 18:51:32', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (26, '405', 5, '豪华单人间', 4, '2023-09-26 18:51:42', '2023-09-26 18:51:42', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (27, '406', 6, '双人套房', 4, '2023-09-26 18:51:54', '2023-09-26 18:51:54', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (28, '407', 7, '单人套房', 4, '2023-09-26 18:52:03', '2023-09-26 18:52:03', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (29, '501', 1, '特护房', 5, '2023-09-26 18:53:54', '2023-09-26 18:53:54', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (31, '502', 2, '普通双人间', 5, '2023-09-26 18:54:05', '2023-09-26 18:54:05', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (32, '503', 3, '普通单人间', 5, '2023-09-26 18:54:12', '2023-09-26 18:54:12', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (33, '504', 4, '豪华双人间', 5, '2023-09-26 18:54:20', '2023-09-26 18:54:20', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (34, '505', 5, '豪华单人间', 5, '2023-09-26 18:54:28', '2023-09-26 18:54:28', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (35, '506', 6, '双人套房', 5, '2023-09-26 18:54:37', '2023-09-26 18:54:37', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (36, '507', 7, '单人套房', 5, '2023-09-26 18:54:47', '2023-09-26 18:54:47', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (37, '601', 1, '特护房', 6, '2023-09-26 18:57:14', '2023-09-26 18:57:14', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (38, '602', 2, '普通双人间', 6, '2023-09-26 18:57:20', '2023-09-26 18:57:20', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (39, '603', 3, '普通单人间', 6, '2023-09-26 18:57:28', '2023-09-26 18:57:28', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (40, '604', 4, '豪华双人间', 6, '2023-09-26 18:57:36', '2023-09-26 18:57:36', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (41, '605', 5, '豪华单人间', 6, '2023-09-26 19:01:36', '2023-09-26 19:01:36', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (42, '606', 6, '双人套房', 6, '2023-09-26 19:01:45', '2023-09-26 19:01:45', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (43, '607', 7, '单人套房', 6, '2023-09-26 19:01:54', '2023-09-26 19:01:54', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (44, '701', 1, '特护房', 7, '2023-09-26 19:02:13', '2023-09-26 19:02:13', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (45, '702', 2, '普通双人间', 7, '2023-09-26 19:02:20', '2023-09-26 19:02:20', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (46, '703', 3, '普通单人间', 7, '2023-09-26 19:02:28', '2023-09-26 19:02:28', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (47, '704', 4, '豪华双人间', 7, '2023-09-26 19:02:49', '2023-09-26 19:02:49', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (48, '705', 5, '豪华单人间', 7, '2023-09-26 19:03:00', '2023-09-26 19:03:00', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (49, '706', 6, '双人套房', 7, '2023-09-26 19:03:07', '2023-09-26 19:03:07', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (50, '707', 7, '单人套房', 7, '2023-09-26 19:03:15', '2023-09-26 19:03:15', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (51, '801', 1, '特护房', 8, '2023-09-26 19:03:49', '2023-09-26 19:03:49', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (52, '802', 2, '普通双人间', 8, '2023-09-26 19:03:57', '2023-09-26 19:03:57', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (53, '803', 3, '普通单人间', 8, '2023-09-26 19:04:04', '2023-09-26 19:04:04', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (54, '804', 4, '豪华双人间', 8, '2023-09-26 19:04:13', '2023-09-26 19:04:13', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (55, '805', 5, '豪华单人间', 8, '2023-09-26 19:04:45', '2023-09-26 19:04:45', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (56, '806', 6, '双人套房', 8, '2023-09-26 19:04:52', '2023-09-26 19:04:52', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (57, '807', 7, '单人套房', 8, '2023-09-26 19:05:00', '2023-09-26 19:05:00', 0, 1671403256519078138, NULL, NULL); +INSERT INTO `room` VALUES (67, '108', 1, '普通单人间', 1, '2023-12-23 16:12:46', '2023-12-23 17:08:47', 0, 1671403256519078138, 1671403256519078138, NULL); +INSERT INTO `room` VALUES (81, '109', 1, '单人套房', 1, '2024-05-27 10:28:37', NULL, 0, 1, NULL, NULL); +INSERT INTO `room` VALUES (83, '1201', 1, '双人套房', 406, '2024-05-27 14:14:54', NULL, 0, 1, NULL, NULL); +INSERT INTO `room` VALUES (86, '102-2', 1, '豪华单人间', 406, '2024-08-22 18:49:21', NULL, 0, 1, NULL, NULL); +INSERT INTO `room` VALUES (89, '110', 1, '双人套房', 1, '2025-02-24 16:30:03', NULL, 0, 1, NULL, NULL); +INSERT INTO `room` VALUES (91, '111', 1, '标准双人间', 1, '2025-02-24 19:19:17', NULL, 0, 1, NULL, NULL); + +-- ---------------------------- +-- Table structure for room_type +-- ---------------------------- +DROP TABLE IF EXISTS `room_type`; +CREATE TABLE `room_type` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '房型名称', + `bed_count` int NOT NULL DEFAULT 0 COMMENT '床位数量', + `price` decimal(10, 2) NOT NULL COMMENT '床位费用', + `introduction` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '介绍', + `photo` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '照片', + `status` tinyint NOT NULL COMMENT '状态,0:禁用,1:启用', + `create_time` datetime NOT NULL COMMENT '创建时间', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `create_by` bigint NULL DEFAULT NULL COMMENT '创建人id', + `update_by` bigint NULL DEFAULT NULL COMMENT '更新人id', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `name`(`name` ASC) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 119 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '房型表' ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of room_type +-- ---------------------------- +INSERT INTO `room_type` VALUES (1, '单人套房', 0, 4000.00, '宽敞舒适的套房,配备独立卫生间和基本生活设施,满足独自居住的需求,提供私密性和舒适度', 'https://yjy-slwl-oss.oss-cn-hangzhou.aliyuncs.com/e2f1031b-e23e-4379-95d4-ce8fe382f58f.png', 1, '2023-09-26 15:57:50', '2024-10-03 23:54:34', 1671403256519078153, 1, NULL); +INSERT INTO `room_type` VALUES (2, '双人套房', 0, 5000.00, '适合夫妻或朋友两人居住的套房,设有独立卫生间和基本生活设施,提供共享空间和私密性', 'https://yjy-slwl-oss.oss-cn-hangzhou.aliyuncs.com/ff84c185-2e28-431c-951d-d004cc2d5bdc.png', 1, '2023-09-26 15:58:51', '2023-09-26 15:58:51', 1671403256519078153, NULL, NULL); +INSERT INTO `room_type` VALUES (3, '豪华单人间', 0, 3000.00, '豪华装修的单人房间,提供舒适的居住环境和高品质的服务,设计精美,配备独立卫生间和必需设施', 'https://yjy-slwl-oss.oss-cn-hangzhou.aliyuncs.com/d803832c-5b93-4cae-ba95-aeb52ab0c5e0.png', 1, '2023-09-26 15:59:33', '2023-09-26 15:59:33', 1671403256519078153, NULL, NULL); +INSERT INTO `room_type` VALUES (4, '豪华双人间', 0, 4500.00, '精心装修的双人房间,提供舒适和豪华的居住环境,配备独立卫生间和高品质的家具', 'https://yjy-slwl-oss.oss-cn-hangzhou.aliyuncs.com/c3522da7-4c5c-48d2-94f9-9f0b95a048d2.png', 1, '2023-09-26 16:00:03', '2024-08-22 16:12:20', 1671403256519078153, 1, NULL); +INSERT INTO `room_type` VALUES (5, '普通单人间', 0, 2000.00, '简洁实用的单人房间,提供基本的居住设施和舒适度,适合独自居住的老年人,提供相对经济实惠的居住选择', 'https://yjy-slwl-oss.oss-cn-hangzhou.aliyuncs.com/1a330b1c-b0a1-463d-8d9a-221ef17c314f.png', 1, '2023-09-26 16:00:27', '2023-09-26 16:00:27', 1671403256519078153, NULL, NULL); +INSERT INTO `room_type` VALUES (103, '普通双人间', 0, 6000.00, '啊傻瓜按个按个', 'https://yjy-slwl-oss.oss-cn-hangzhou.aliyuncs.com/9c4a9926-2f58-4306-a8c5-122adb8e700e.jpeg', 0, '2023-12-25 16:04:00', '2025-02-24 16:06:37', 1671403256519078138, 1, NULL); +INSERT INTO `room_type` VALUES (116, '标准双人间', 10, 1500.00, '123', 'https://itheim.oss-cn-beijing.aliyuncs.com/91c4a814-efd5-4093-a5ac-963b41047019.png', 1, '2024-09-12 22:52:36', '2024-09-12 22:55:10', 1, 1, '123'); +INSERT INTO `room_type` VALUES (117, '豪华三人间', 3, 1000.00, '豪华三人间', 'https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/24/c63b185301aa44fb81a00fc8818fa010.png', 0, '2025-02-24 15:43:09', '2025-02-24 19:18:46', 1, 1, NULL); +INSERT INTO `room_type` VALUES (118, '特护房', 1, 6000.00, '特护房型', 'https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/24/a117e4c5c7484176a50bb6cf7daa48fa.png', 1, '2025-02-24 16:06:26', '2025-02-24 16:06:32', 1, 1, NULL); + +-- ---------------------------- +-- Table structure for sys_config +-- ---------------------------- +DROP TABLE IF EXISTS `sys_config`; +CREATE TABLE `sys_config` ( + `config_id` int NOT NULL AUTO_INCREMENT COMMENT '参数主键', + `config_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '参数名称', + `config_key` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '参数键名', + `config_value` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '参数键值', + `config_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT 'N' COMMENT '系统内置(Y是 N否)', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`config_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 100 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '参数配置表' ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of sys_config +-- ---------------------------- +INSERT INTO `sys_config` VALUES (1, '主框架页-默认皮肤样式名称', 'sys.index.skinName', 'skin-blue', 'Y', 'admin', '2024-08-14 02:48:24', '', NULL, '蓝色 skin-blue、绿色 skin-green、紫色 skin-purple、红色 skin-red、黄色 skin-yellow'); +INSERT INTO `sys_config` VALUES (2, '用户管理-账号初始密码', 'sys.user.initPassword', '123456', 'Y', 'admin', '2024-08-14 02:48:24', '', NULL, '初始化密码 123456'); +INSERT INTO `sys_config` VALUES (3, '主框架页-侧边栏主题', 'sys.index.sideTheme', 'theme-dark', 'Y', 'admin', '2024-08-14 02:48:24', '', NULL, '深色主题theme-dark,浅色主题theme-light'); +INSERT INTO `sys_config` VALUES (4, '账号自助-验证码开关', 'sys.account.captchaEnabled', 'true', 'Y', 'admin', '2024-08-14 02:48:24', '', NULL, '是否开启验证码功能(true开启,false关闭)'); +INSERT INTO `sys_config` VALUES (5, '账号自助-是否开启用户注册功能', 'sys.account.registerUser', 'false', 'Y', 'admin', '2024-08-14 02:48:24', '', NULL, '是否开启注册用户功能(true开启,false关闭)'); +INSERT INTO `sys_config` VALUES (6, '用户登录-黑名单列表', 'sys.login.blackIPList', '', 'Y', 'admin', '2024-08-14 02:48:24', '', NULL, '设置登录IP黑名单限制,多个匹配项以;分隔,支持匹配(*通配、网段)'); + +-- ---------------------------- +-- Table structure for sys_dept +-- ---------------------------- +DROP TABLE IF EXISTS `sys_dept`; +CREATE TABLE `sys_dept` ( + `dept_id` bigint NOT NULL AUTO_INCREMENT COMMENT '部门id', + `parent_id` bigint NULL DEFAULT 0 COMMENT '父部门id', + `ancestors` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '祖级列表', + `dept_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '部门名称', + `order_num` int NULL DEFAULT 0 COMMENT '显示顺序', + `leader` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '负责人', + `phone` varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '联系电话', + `email` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '邮箱', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '0' COMMENT '部门状态(0正常 1停用)', + `del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`dept_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 204 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '部门表' ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of sys_dept +-- ---------------------------- +INSERT INTO `sys_dept` VALUES (100, 0, '0', '智慧养老院', 0, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2024-08-14 02:48:23', 'admin', '2024-10-18 10:08:30'); +INSERT INTO `sys_dept` VALUES (101, 100, '0,100', '高层办公室', 1, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2024-08-14 02:48:23', 'admin', '2024-10-18 10:08:40'); +INSERT INTO `sys_dept` VALUES (102, 100, '0,100', '财务部', 2, '', '', '', '0', '0', 'admin', '2024-08-14 02:48:23', 'admin', '2024-10-18 10:11:02'); +INSERT INTO `sys_dept` VALUES (103, 101, '0,100,101', '院长办公室', 1, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2024-08-14 02:48:23', 'admin', '2024-10-18 10:08:55'); +INSERT INTO `sys_dept` VALUES (104, 101, '0,100,101', '市场部门', 2, '若依', '15888888888', 'ry@qq.com', '0', '2', 'admin', '2024-08-14 02:48:23', '', NULL); +INSERT INTO `sys_dept` VALUES (105, 101, '0,100,101', '测试部门', 3, '若依', '15888888888', 'ry@qq.com', '0', '2', 'admin', '2024-08-14 02:48:23', '', NULL); +INSERT INTO `sys_dept` VALUES (106, 101, '0,100,101', '财务部门', 4, '若依', '15888888888', 'ry@qq.com', '0', '2', 'admin', '2024-08-14 02:48:23', '', NULL); +INSERT INTO `sys_dept` VALUES (107, 101, '0,100,101', '运维部门', 5, '若依', '15888888888', 'ry@qq.com', '0', '2', 'admin', '2024-08-14 02:48:23', '', NULL); +INSERT INTO `sys_dept` VALUES (108, 102, '0,100,102', '市场部门', 1, '若依', '15888888888', 'ry@qq.com', '0', '2', 'admin', '2024-08-14 02:48:23', '', NULL); +INSERT INTO `sys_dept` VALUES (109, 102, '0,100,102', '财务部门', 2, '若依', '15888888888', 'ry@qq.com', '0', '2', 'admin', '2024-08-14 02:48:23', '', NULL); +INSERT INTO `sys_dept` VALUES (200, 100, '0,100', '行政部', 3, NULL, NULL, NULL, '0', '0', 'admin', '2024-10-18 10:10:44', '', NULL); +INSERT INTO `sys_dept` VALUES (201, 100, '0,100', '护理部', 4, NULL, NULL, NULL, '0', '0', 'admin', '2024-10-18 10:10:55', '', NULL); +INSERT INTO `sys_dept` VALUES (202, 100, '0,100', '后勤部', 5, NULL, NULL, NULL, '0', '0', 'admin', '2024-10-18 10:11:15', '', NULL); +INSERT INTO `sys_dept` VALUES (203, 100, '0,100', '销售部', 6, NULL, NULL, NULL, '0', '0', 'admin', '2024-10-18 10:11:24', '', NULL); + +-- ---------------------------- +-- Table structure for sys_dict_data +-- ---------------------------- +DROP TABLE IF EXISTS `sys_dict_data`; +CREATE TABLE `sys_dict_data` ( + `dict_code` bigint NOT NULL AUTO_INCREMENT COMMENT '字典编码', + `dict_sort` int NULL DEFAULT 0 COMMENT '字典排序', + `dict_label` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '字典标签', + `dict_value` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '字典键值', + `dict_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '字典类型', + `css_class` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '样式属性(其他样式扩展)', + `list_class` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '表格回显样式', + `is_default` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT 'N' COMMENT '是否默认(Y是 N否)', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '0' COMMENT '状态(0正常 1停用)', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`dict_code`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 109 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '字典数据表' ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of sys_dict_data +-- ---------------------------- +INSERT INTO `sys_dict_data` VALUES (1, 1, '男', '0', 'sys_user_sex', '', '', 'Y', '0', 'admin', '2024-08-14 02:48:24', '', NULL, '性别男'); +INSERT INTO `sys_dict_data` VALUES (2, 2, '女', '1', 'sys_user_sex', '', '', 'N', '0', 'admin', '2024-08-14 02:48:24', '', NULL, '性别女'); +INSERT INTO `sys_dict_data` VALUES (3, 3, '未知', '2', 'sys_user_sex', '', '', 'N', '0', 'admin', '2024-08-14 02:48:24', '', NULL, '性别未知'); +INSERT INTO `sys_dict_data` VALUES (4, 1, '显示', '0', 'sys_show_hide', '', 'primary', 'Y', '0', 'admin', '2024-08-14 02:48:24', '', NULL, '显示菜单'); +INSERT INTO `sys_dict_data` VALUES (5, 2, '隐藏', '1', 'sys_show_hide', '', 'danger', 'N', '0', 'admin', '2024-08-14 02:48:24', '', NULL, '隐藏菜单'); +INSERT INTO `sys_dict_data` VALUES (6, 1, '正常', '0', 'sys_normal_disable', '', 'primary', 'Y', '0', 'admin', '2024-08-14 02:48:24', '', NULL, '正常状态'); +INSERT INTO `sys_dict_data` VALUES (7, 2, '停用', '1', 'sys_normal_disable', '', 'danger', 'N', '0', 'admin', '2024-08-14 02:48:24', '', NULL, '停用状态'); +INSERT INTO `sys_dict_data` VALUES (8, 1, '正常', '0', 'sys_job_status', '', 'primary', 'Y', '0', 'admin', '2024-08-14 02:48:24', '', NULL, '正常状态'); +INSERT INTO `sys_dict_data` VALUES (9, 2, '暂停', '1', 'sys_job_status', '', 'danger', 'N', '0', 'admin', '2024-08-14 02:48:24', '', NULL, '停用状态'); +INSERT INTO `sys_dict_data` VALUES (10, 1, '默认', 'DEFAULT', 'sys_job_group', '', '', 'Y', '0', 'admin', '2024-08-14 02:48:24', '', NULL, '默认分组'); +INSERT INTO `sys_dict_data` VALUES (11, 2, '系统', 'SYSTEM', 'sys_job_group', '', '', 'N', '0', 'admin', '2024-08-14 02:48:24', '', NULL, '系统分组'); +INSERT INTO `sys_dict_data` VALUES (12, 1, '是', 'Y', 'sys_yes_no', '', 'primary', 'Y', '0', 'admin', '2024-08-14 02:48:24', '', NULL, '系统默认是'); +INSERT INTO `sys_dict_data` VALUES (13, 2, '否', 'N', 'sys_yes_no', '', 'danger', 'N', '0', 'admin', '2024-08-14 02:48:24', '', NULL, '系统默认否'); +INSERT INTO `sys_dict_data` VALUES (14, 1, '通知', '1', 'sys_notice_type', '', 'warning', 'Y', '0', 'admin', '2024-08-14 02:48:24', '', NULL, '通知'); +INSERT INTO `sys_dict_data` VALUES (15, 2, '公告', '2', 'sys_notice_type', '', 'success', 'N', '0', 'admin', '2024-08-14 02:48:24', '', NULL, '公告'); +INSERT INTO `sys_dict_data` VALUES (16, 1, '正常', '0', 'sys_notice_status', '', 'primary', 'Y', '0', 'admin', '2024-08-14 02:48:24', '', NULL, '正常状态'); +INSERT INTO `sys_dict_data` VALUES (17, 2, '关闭', '1', 'sys_notice_status', '', 'danger', 'N', '0', 'admin', '2024-08-14 02:48:24', '', NULL, '关闭状态'); +INSERT INTO `sys_dict_data` VALUES (18, 99, '其他', '0', 'sys_oper_type', '', 'info', 'N', '0', 'admin', '2024-08-14 02:48:24', '', NULL, '其他操作'); +INSERT INTO `sys_dict_data` VALUES (19, 1, '新增', '1', 'sys_oper_type', '', 'info', 'N', '0', 'admin', '2024-08-14 02:48:24', '', NULL, '新增操作'); +INSERT INTO `sys_dict_data` VALUES (20, 2, '修改', '2', 'sys_oper_type', '', 'info', 'N', '0', 'admin', '2024-08-14 02:48:24', '', NULL, '修改操作'); +INSERT INTO `sys_dict_data` VALUES (21, 3, '删除', '3', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', '2024-08-14 02:48:24', '', NULL, '删除操作'); +INSERT INTO `sys_dict_data` VALUES (22, 4, '授权', '4', 'sys_oper_type', '', 'primary', 'N', '0', 'admin', '2024-08-14 02:48:24', '', NULL, '授权操作'); +INSERT INTO `sys_dict_data` VALUES (23, 5, '导出', '5', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', '2024-08-14 02:48:24', '', NULL, '导出操作'); +INSERT INTO `sys_dict_data` VALUES (24, 6, '导入', '6', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', '2024-08-14 02:48:24', '', NULL, '导入操作'); +INSERT INTO `sys_dict_data` VALUES (25, 7, '强退', '7', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', '2024-08-14 02:48:24', '', NULL, '强退操作'); +INSERT INTO `sys_dict_data` VALUES (26, 8, '生成代码', '8', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', '2024-08-14 02:48:24', '', NULL, '生成操作'); +INSERT INTO `sys_dict_data` VALUES (27, 9, '清空数据', '9', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', '2024-08-14 02:48:24', '', NULL, '清空操作'); +INSERT INTO `sys_dict_data` VALUES (28, 1, '成功', '0', 'sys_common_status', '', 'primary', 'N', '0', 'admin', '2024-08-14 02:48:24', '', NULL, '正常状态'); +INSERT INTO `sys_dict_data` VALUES (29, 2, '失败', '1', 'sys_common_status', '', 'danger', 'N', '0', 'admin', '2024-08-14 02:48:24', '', NULL, '停用状态'); +INSERT INTO `sys_dict_data` VALUES (100, 0, '启用', '1', 'nursing_project_status', NULL, 'default', 'N', '0', 'admin', '2024-08-18 02:41:15', '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (101, 0, '禁用', '0', 'nursing_project_status', NULL, 'default', 'N', '0', 'admin', '2024-08-18 02:41:30', '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (103, 0, '启用', '1', 'nursing_plan_status', NULL, 'default', 'N', '0', 'admin', '2024-08-19 11:00:04', '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (104, 0, '禁用', '0', 'nursing_plan_status', NULL, 'default', 'N', '0', 'admin', '2024-08-19 11:00:10', 'admin', '2025-02-24 02:13:37', NULL); +INSERT INTO `sys_dict_data` VALUES (105, 0, '启用', '1', 'nursing_level_status', NULL, 'default', 'N', '0', 'admin', '2024-08-20 03:04:14', '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (106, 0, '禁用', '0', 'nursing_level_status', NULL, 'default', 'N', '0', 'admin', '2024-08-20 03:04:21', '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (107, 0, '已入住', '0', 'admission_status', NULL, 'default', 'N', '0', 'admin', '2024-08-31 03:20:26', '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (108, 0, '未入住', '1', 'admission_status', NULL, 'default', 'N', '0', 'admin', '2024-08-31 03:20:35', '', NULL, NULL); + +-- ---------------------------- +-- Table structure for sys_dict_type +-- ---------------------------- +DROP TABLE IF EXISTS `sys_dict_type`; +CREATE TABLE `sys_dict_type` ( + `dict_id` bigint NOT NULL AUTO_INCREMENT COMMENT '字典主键', + `dict_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '字典名称', + `dict_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '字典类型', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '0' COMMENT '状态(0正常 1停用)', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`dict_id`) USING BTREE, + UNIQUE INDEX `dict_type`(`dict_type` ASC) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 104 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '字典类型表' ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of sys_dict_type +-- ---------------------------- +INSERT INTO `sys_dict_type` VALUES (1, '用户性别', 'sys_user_sex', '0', 'admin', '2024-08-14 02:48:24', '', NULL, '用户性别列表'); +INSERT INTO `sys_dict_type` VALUES (2, '菜单状态', 'sys_show_hide', '0', 'admin', '2024-08-14 02:48:24', '', NULL, '菜单状态列表'); +INSERT INTO `sys_dict_type` VALUES (3, '系统开关', 'sys_normal_disable', '0', 'admin', '2024-08-14 02:48:24', '', NULL, '系统开关列表'); +INSERT INTO `sys_dict_type` VALUES (4, '任务状态', 'sys_job_status', '0', 'admin', '2024-08-14 02:48:24', '', NULL, '任务状态列表'); +INSERT INTO `sys_dict_type` VALUES (5, '任务分组', 'sys_job_group', '0', 'admin', '2024-08-14 02:48:24', '', NULL, '任务分组列表'); +INSERT INTO `sys_dict_type` VALUES (6, '系统是否', 'sys_yes_no', '0', 'admin', '2024-08-14 02:48:24', '', NULL, '系统是否列表'); +INSERT INTO `sys_dict_type` VALUES (7, '通知类型', 'sys_notice_type', '0', 'admin', '2024-08-14 02:48:24', '', NULL, '通知类型列表'); +INSERT INTO `sys_dict_type` VALUES (8, '通知状态', 'sys_notice_status', '0', 'admin', '2024-08-14 02:48:24', '', NULL, '通知状态列表'); +INSERT INTO `sys_dict_type` VALUES (9, '操作类型', 'sys_oper_type', '0', 'admin', '2024-08-14 02:48:24', '', NULL, '操作类型列表'); +INSERT INTO `sys_dict_type` VALUES (10, '系统状态', 'sys_common_status', '0', 'admin', '2024-08-14 02:48:24', '', NULL, '登录状态列表'); +INSERT INTO `sys_dict_type` VALUES (100, '护理项目状态', 'nursing_project_status', '0', 'admin', '2024-08-18 02:40:48', '', NULL, NULL); +INSERT INTO `sys_dict_type` VALUES (101, '护理计划状态', 'nursing_plan_status', '0', 'admin', '2024-08-19 10:59:40', '', NULL, NULL); +INSERT INTO `sys_dict_type` VALUES (102, '护理等级状态', 'nursing_level_status', '0', 'admin', '2024-08-20 03:04:03', '', NULL, NULL); +INSERT INTO `sys_dict_type` VALUES (103, '健康评估-入住状态', 'admission_status', '0', 'admin', '2024-08-31 03:19:57', '', NULL, NULL); + +-- ---------------------------- +-- Table structure for sys_job +-- ---------------------------- +DROP TABLE IF EXISTS `sys_job`; +CREATE TABLE `sys_job` ( + `job_id` bigint NOT NULL AUTO_INCREMENT COMMENT '任务ID', + `job_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '任务名称', + `job_group` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'DEFAULT' COMMENT '任务组名', + `invoke_target` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '调用目标字符串', + `cron_expression` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT 'cron执行表达式', + `misfire_policy` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '3' COMMENT '计划执行错误策略(1立即执行 2执行一次 3放弃执行)', + `concurrent` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '1' COMMENT '是否并发执行(0允许 1禁止)', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '0' COMMENT '状态(0正常 1暂停)', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '备注信息', + PRIMARY KEY (`job_id`, `job_name`, `job_group`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 102 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '定时任务调度表' ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of sys_job +-- ---------------------------- +INSERT INTO `sys_job` VALUES (1, '系统默认(无参)', 'DEFAULT', 'ryTask.ryNoParams', '0/10 * * * * ?', '3', '1', '1', 'admin', '2024-08-14 02:48:24', '', NULL, ''); +INSERT INTO `sys_job` VALUES (2, '系统默认(有参)', 'DEFAULT', 'ryTask.ryParams(\'ry\')', '0/15 * * * * ?', '3', '1', '1', 'admin', '2024-08-14 02:48:24', '', NULL, ''); +INSERT INTO `sys_job` VALUES (3, '系统默认(多参)', 'DEFAULT', 'ryTask.ryMultipleParams(\'ry\', true, 2000L, 316.50D, 100)', '0/20 * * * * ?', '3', '1', '1', 'admin', '2024-08-14 02:48:24', '', NULL, ''); +INSERT INTO `sys_job` VALUES (100, '测试1', 'DEFAULT', 'myJob.executeTask', '0/3 * * * * ?', '1', '1', '1', 'admin', '2025-02-27 09:21:19', 'admin', '2025-02-27 09:23:59', ''); +INSERT INTO `sys_job` VALUES (101, '合同状态更新', 'DEFAULT', 'contractJob.updateContractStatus', '0 1 0 * * ?', '1', '1', '0', 'admin', '2025-02-27 11:25:06', '', '2025-02-27 11:49:37', ''); + +-- ---------------------------- +-- Table structure for sys_job_log +-- ---------------------------- +DROP TABLE IF EXISTS `sys_job_log`; +CREATE TABLE `sys_job_log` ( + `job_log_id` bigint NOT NULL AUTO_INCREMENT COMMENT '任务日志ID', + `job_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '任务名称', + `job_group` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '任务组名', + `invoke_target` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '调用目标字符串', + `job_message` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '日志信息', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '0' COMMENT '执行状态(0正常 1失败)', + `exception_info` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '异常信息', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + PRIMARY KEY (`job_log_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 25 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '定时任务调度日志表' ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of sys_job_log +-- ---------------------------- +INSERT INTO `sys_job_log` VALUES (1, '测试1', 'DEFAULT', 'myJob.executeTask', '测试1 总共耗时:3毫秒', '0', '', '2025-02-27 09:21:28'); +INSERT INTO `sys_job_log` VALUES (2, '测试1', 'DEFAULT', 'myJob.executeTask', '测试1 总共耗时:4毫秒', '0', '', '2025-02-27 09:23:32'); +INSERT INTO `sys_job_log` VALUES (3, '测试1', 'DEFAULT', 'myJob.executeTask', '测试1 总共耗时:1毫秒', '0', '', '2025-02-27 09:23:35'); +INSERT INTO `sys_job_log` VALUES (4, '测试1', 'DEFAULT', 'myJob.executeTask', '测试1 总共耗时:1毫秒', '0', '', '2025-02-27 09:23:38'); +INSERT INTO `sys_job_log` VALUES (5, '测试1', 'DEFAULT', 'myJob.executeTask', '测试1 总共耗时:0毫秒', '0', '', '2025-02-27 09:23:41'); +INSERT INTO `sys_job_log` VALUES (6, '测试1', 'DEFAULT', 'myJob.executeTask', '测试1 总共耗时:0毫秒', '0', '', '2025-02-27 09:23:44'); +INSERT INTO `sys_job_log` VALUES (7, '测试1', 'DEFAULT', 'myJob.executeTask', '测试1 总共耗时:1毫秒', '0', '', '2025-02-27 09:23:47'); +INSERT INTO `sys_job_log` VALUES (8, '测试1', 'DEFAULT', 'myJob.executeTask', '测试1 总共耗时:0毫秒', '0', '', '2025-02-27 09:23:50'); +INSERT INTO `sys_job_log` VALUES (9, '测试1', 'DEFAULT', 'myJob.executeTask', '测试1 总共耗时:0毫秒', '0', '', '2025-02-27 09:23:53'); +INSERT INTO `sys_job_log` VALUES (10, '测试1', 'DEFAULT', 'myJob.executeTask', '测试1 总共耗时:1毫秒', '0', '', '2025-02-27 09:23:56'); +INSERT INTO `sys_job_log` VALUES (11, '测试1', 'DEFAULT', 'myJob.executeTask', '测试1 总共耗时:1毫秒', '0', '', '2025-02-27 09:23:59'); +INSERT INTO `sys_job_log` VALUES (12, '合同状态更新', 'DEFAULT', 'contractJob.updateContractStatus', '合同状态更新 总共耗时:67毫秒', '1', 'java.lang.reflect.InvocationTargetException\r\n at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\r\n at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\r\n at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\r\n at java.base/java.lang.reflect.Method.invoke(Method.java:566)\r\n at com.zzyl.quartz.util.JobInvokeUtil.invokeMethod(JobInvokeUtil.java:61)\r\n at com.zzyl.quartz.util.JobInvokeUtil.invokeMethod(JobInvokeUtil.java:33)\r\n at com.zzyl.quartz.util.QuartzDisallowConcurrentExecution.doExecute(QuartzDisallowConcurrentExecution.java:19)\r\n at com.zzyl.quartz.util.AbstractQuartzJob.execute(AbstractQuartzJob.java:43)\r\n at org.quartz.core.JobRunShell.run(JobRunShell.java:202)\r\n at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)\r\nCaused by: cn.hutool.core.bean.BeanException: 将合同状态由 “未生效” 更新为 “已生效” 失败!\r\n at com.zzyl.nursing.service.impl.ContractServiceImpl.updateContractStatus(ContractServiceImpl.java:114)\r\n at com.zzyl.nursing.service.impl.ContractServiceImpl$$FastClassBySpringCGLIB$$383f1c90.invoke()\r\n at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:792)\r\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:762)\r\n at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)\r\n at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388)\r\n at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)\r\n at org.springframework.aop.framewo', '2025-02-27 11:25:14'); +INSERT INTO `sys_job_log` VALUES (13, '合同状态更新', 'DEFAULT', 'contractJob.updateContractStatus', '合同状态更新 总共耗时:14毫秒', '1', 'java.lang.reflect.InvocationTargetException\r\n at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\r\n at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\r\n at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\r\n at java.base/java.lang.reflect.Method.invoke(Method.java:566)\r\n at com.zzyl.quartz.util.JobInvokeUtil.invokeMethod(JobInvokeUtil.java:61)\r\n at com.zzyl.quartz.util.JobInvokeUtil.invokeMethod(JobInvokeUtil.java:33)\r\n at com.zzyl.quartz.util.QuartzDisallowConcurrentExecution.doExecute(QuartzDisallowConcurrentExecution.java:19)\r\n at com.zzyl.quartz.util.AbstractQuartzJob.execute(AbstractQuartzJob.java:43)\r\n at org.quartz.core.JobRunShell.run(JobRunShell.java:202)\r\n at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)\r\nCaused by: cn.hutool.core.bean.BeanException: 将合同状态由 “未生效” 更新为 “已生效” 失败!\r\n at com.zzyl.nursing.service.impl.ContractServiceImpl.updateContractStatus(ContractServiceImpl.java:114)\r\n at com.zzyl.nursing.service.impl.ContractServiceImpl$$FastClassBySpringCGLIB$$383f1c90.invoke()\r\n at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:792)\r\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:762)\r\n at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)\r\n at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388)\r\n at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)\r\n at org.springframework.aop.framewo', '2025-02-27 11:27:12'); +INSERT INTO `sys_job_log` VALUES (14, '合同状态更新', 'DEFAULT', 'contractJob.updateContractStatus', '合同状态更新 总共耗时:59毫秒', '1', 'java.lang.reflect.InvocationTargetException\r\n at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\r\n at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\r\n at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\r\n at java.base/java.lang.reflect.Method.invoke(Method.java:566)\r\n at com.zzyl.quartz.util.JobInvokeUtil.invokeMethod(JobInvokeUtil.java:61)\r\n at com.zzyl.quartz.util.JobInvokeUtil.invokeMethod(JobInvokeUtil.java:33)\r\n at com.zzyl.quartz.util.QuartzDisallowConcurrentExecution.doExecute(QuartzDisallowConcurrentExecution.java:19)\r\n at com.zzyl.quartz.util.AbstractQuartzJob.execute(AbstractQuartzJob.java:43)\r\n at org.quartz.core.JobRunShell.run(JobRunShell.java:202)\r\n at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)\r\nCaused by: cn.hutool.core.bean.BeanException: 将合同状态由 “未生效” 更新为 “已生效” 失败!\r\n at com.zzyl.nursing.service.impl.ContractServiceImpl.updateContractStatus(ContractServiceImpl.java:114)\r\n at com.zzyl.nursing.service.impl.ContractServiceImpl$$FastClassBySpringCGLIB$$383f1c90.invoke()\r\n at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:792)\r\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:762)\r\n at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)\r\n at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388)\r\n at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)\r\n at org.springframework.aop.framewo', '2025-02-27 11:28:26'); +INSERT INTO `sys_job_log` VALUES (15, '合同状态更新', 'DEFAULT', 'contractJob.updateContractStatus', '合同状态更新 总共耗时:24867毫秒', '1', 'java.lang.reflect.InvocationTargetException\r\n at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\r\n at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\r\n at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\r\n at java.base/java.lang.reflect.Method.invoke(Method.java:566)\r\n at com.zzyl.quartz.util.JobInvokeUtil.invokeMethod(JobInvokeUtil.java:61)\r\n at com.zzyl.quartz.util.JobInvokeUtil.invokeMethod(JobInvokeUtil.java:33)\r\n at com.zzyl.quartz.util.QuartzDisallowConcurrentExecution.doExecute(QuartzDisallowConcurrentExecution.java:19)\r\n at com.zzyl.quartz.util.AbstractQuartzJob.execute(AbstractQuartzJob.java:43)\r\n at org.quartz.core.JobRunShell.run(JobRunShell.java:202)\r\n at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)\r\nCaused by: cn.hutool.core.bean.BeanException: 将合同状态由 “未生效” 更新为 “已生效” 失败!\r\n at com.zzyl.nursing.service.impl.ContractServiceImpl.updateContractStatus(ContractServiceImpl.java:114)\r\n at com.zzyl.nursing.service.impl.ContractServiceImpl$$FastClassBySpringCGLIB$$383f1c90.invoke()\r\n at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:792)\r\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:762)\r\n at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)\r\n at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388)\r\n at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)\r\n at org.springframework.aop.framewo', '2025-02-27 11:29:34'); +INSERT INTO `sys_job_log` VALUES (16, '合同状态更新', 'DEFAULT', 'contractJob.updateContractStatus', '合同状态更新 总共耗时:153989毫秒', '1', 'java.lang.reflect.InvocationTargetException\r\n at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\r\n at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\r\n at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\r\n at java.base/java.lang.reflect.Method.invoke(Method.java:566)\r\n at com.zzyl.quartz.util.JobInvokeUtil.invokeMethod(JobInvokeUtil.java:61)\r\n at com.zzyl.quartz.util.JobInvokeUtil.invokeMethod(JobInvokeUtil.java:33)\r\n at com.zzyl.quartz.util.QuartzDisallowConcurrentExecution.doExecute(QuartzDisallowConcurrentExecution.java:19)\r\n at com.zzyl.quartz.util.AbstractQuartzJob.execute(AbstractQuartzJob.java:43)\r\n at org.quartz.core.JobRunShell.run(JobRunShell.java:202)\r\n at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)\r\nCaused by: cn.hutool.core.bean.BeanException: 将合同状态由 “未生效” 更新为 “已生效” 失败!\r\n at com.zzyl.nursing.service.impl.ContractServiceImpl.updateContractStatus(Unknown Source)\r\n at com.zzyl.nursing.service.impl.ContractServiceImpl$$FastClassBySpringCGLIB$$383f1c90.invoke()\r\n at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:792)\r\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:762)\r\n at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)\r\n at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388)\r\n at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)\r\n at org.springframework.aop.framework.ReflectiveM', '2025-02-27 11:32:14'); +INSERT INTO `sys_job_log` VALUES (17, '合同状态更新', 'DEFAULT', 'contractJob.updateContractStatus', '合同状态更新 总共耗时:46057毫秒', '0', '', '2025-02-27 11:33:16'); +INSERT INTO `sys_job_log` VALUES (18, '合同状态更新', 'DEFAULT', 'contractJob.updateContractStatus', '合同状态更新 总共耗时:138毫秒', '1', 'java.lang.reflect.InvocationTargetException\r\n at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\r\n at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\r\n at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\r\n at java.base/java.lang.reflect.Method.invoke(Method.java:566)\r\n at com.zzyl.quartz.util.JobInvokeUtil.invokeMethod(JobInvokeUtil.java:61)\r\n at com.zzyl.quartz.util.JobInvokeUtil.invokeMethod(JobInvokeUtil.java:33)\r\n at com.zzyl.quartz.util.QuartzDisallowConcurrentExecution.doExecute(QuartzDisallowConcurrentExecution.java:19)\r\n at com.zzyl.quartz.util.AbstractQuartzJob.execute(AbstractQuartzJob.java:43)\r\n at org.quartz.core.JobRunShell.run(JobRunShell.java:202)\r\n at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)\r\nCaused by: cn.hutool.core.bean.BeanException: 将合同状态由 “已生效” 更新为 “已失效” 失败!\r\n at com.zzyl.nursing.service.impl.ContractServiceImpl.updateContractStatus(ContractServiceImpl.java:122)\r\n at com.zzyl.nursing.service.impl.ContractServiceImpl$$FastClassBySpringCGLIB$$383f1c90.invoke()\r\n at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:792)\r\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:762)\r\n at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)\r\n at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388)\r\n at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)\r\n at org.springframework.aop.framewo', '2025-02-27 11:33:54'); +INSERT INTO `sys_job_log` VALUES (19, '合同状态更新', 'DEFAULT', 'contractJob.updateContractStatus', '合同状态更新 总共耗时:96863毫秒', '1', 'java.lang.reflect.InvocationTargetException\r\n at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\r\n at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\r\n at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\r\n at java.base/java.lang.reflect.Method.invoke(Method.java:566)\r\n at com.zzyl.quartz.util.JobInvokeUtil.invokeMethod(JobInvokeUtil.java:61)\r\n at com.zzyl.quartz.util.JobInvokeUtil.invokeMethod(JobInvokeUtil.java:33)\r\n at com.zzyl.quartz.util.QuartzDisallowConcurrentExecution.doExecute(QuartzDisallowConcurrentExecution.java:19)\r\n at com.zzyl.quartz.util.AbstractQuartzJob.execute(AbstractQuartzJob.java:43)\r\n at org.quartz.core.JobRunShell.run(JobRunShell.java:202)\r\n at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)\r\nCaused by: cn.hutool.core.bean.BeanException: 将合同状态由 “已生效” 更新为 “已失效” 失败!\r\n at com.zzyl.nursing.service.impl.ContractServiceImpl.updateContractStatus(ContractServiceImpl.java:122)\r\n at com.zzyl.nursing.service.impl.ContractServiceImpl$$FastClassBySpringCGLIB$$383f1c90.invoke()\r\n at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:792)\r\n at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)\r\n at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:762)\r\n at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)\r\n at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388)\r\n at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)\r\n at org.springframework.aop.framewo', '2025-02-27 11:35:50'); +INSERT INTO `sys_job_log` VALUES (20, '合同状态更新', 'DEFAULT', 'contractJob.updateContractStatus', '合同状态更新 总共耗时:8214毫秒', '0', '', '2025-02-27 11:36:18'); +INSERT INTO `sys_job_log` VALUES (21, '合同状态更新', 'DEFAULT', 'contractJob.updateContractStatus', '合同状态更新 总共耗时:157毫秒', '0', '', '2025-02-27 11:40:20'); +INSERT INTO `sys_job_log` VALUES (22, '合同状态更新', 'DEFAULT', 'contractJob.updateContractStatus', '合同状态更新 总共耗时:65毫秒', '0', '', '2025-02-27 11:42:16'); +INSERT INTO `sys_job_log` VALUES (23, '合同状态更新', 'DEFAULT', 'contractJob.updateContractStatus', '合同状态更新 总共耗时:71683毫秒', '0', '', '2025-02-27 11:44:10'); +INSERT INTO `sys_job_log` VALUES (24, '合同状态更新', 'DEFAULT', 'contractJob.updateContractStatus', '合同状态更新 总共耗时:57毫秒', '0', '', '2025-02-27 11:44:40'); + +-- ---------------------------- +-- Table structure for sys_logininfor +-- ---------------------------- +DROP TABLE IF EXISTS `sys_logininfor`; +CREATE TABLE `sys_logininfor` ( + `info_id` bigint NOT NULL AUTO_INCREMENT COMMENT '访问ID', + `user_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '用户账号', + `ipaddr` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '登录IP地址', + `login_location` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '登录地点', + `browser` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '浏览器类型', + `os` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '操作系统', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '0' COMMENT '登录状态(0成功 1失败)', + `msg` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '提示消息', + `login_time` datetime NULL DEFAULT NULL COMMENT '访问时间', + PRIMARY KEY (`info_id`) USING BTREE, + INDEX `idx_sys_logininfor_s`(`status` ASC) USING BTREE, + INDEX `idx_sys_logininfor_lt`(`login_time` ASC) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 223 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '系统访问记录' ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of sys_logininfor +-- ---------------------------- +INSERT INTO `sys_logininfor` VALUES (100, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-14 02:54:16'); +INSERT INTO `sys_logininfor` VALUES (101, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '退出成功', '2024-08-14 03:20:32'); +INSERT INTO `sys_logininfor` VALUES (102, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-14 03:20:40'); +INSERT INTO `sys_logininfor` VALUES (103, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-14 04:21:52'); +INSERT INTO `sys_logininfor` VALUES (104, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-14 07:36:43'); +INSERT INTO `sys_logininfor` VALUES (105, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-14 07:49:48'); +INSERT INTO `sys_logininfor` VALUES (106, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-14 08:24:37'); +INSERT INTO `sys_logininfor` VALUES (107, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '退出成功', '2024-08-14 08:32:48'); +INSERT INTO `sys_logininfor` VALUES (108, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-14 08:32:52'); +INSERT INTO `sys_logininfor` VALUES (109, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '1', '验证码错误', '2024-08-18 01:47:10'); +INSERT INTO `sys_logininfor` VALUES (110, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-18 01:47:14'); +INSERT INTO `sys_logininfor` VALUES (111, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '1', '验证码错误', '2024-08-18 02:40:15'); +INSERT INTO `sys_logininfor` VALUES (112, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-18 02:40:18'); +INSERT INTO `sys_logininfor` VALUES (113, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-18 03:46:09'); +INSERT INTO `sys_logininfor` VALUES (114, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-18 04:34:20'); +INSERT INTO `sys_logininfor` VALUES (115, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-18 06:15:19'); +INSERT INTO `sys_logininfor` VALUES (116, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-18 07:08:20'); +INSERT INTO `sys_logininfor` VALUES (117, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-18 11:24:56'); +INSERT INTO `sys_logininfor` VALUES (118, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-19 02:22:04'); +INSERT INTO `sys_logininfor` VALUES (119, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-19 07:14:04'); +INSERT INTO `sys_logininfor` VALUES (120, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-19 08:46:55'); +INSERT INTO `sys_logininfor` VALUES (121, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-19 10:58:07'); +INSERT INTO `sys_logininfor` VALUES (122, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-19 12:19:50'); +INSERT INTO `sys_logininfor` VALUES (123, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-19 13:26:44'); +INSERT INTO `sys_logininfor` VALUES (124, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-19 14:33:19'); +INSERT INTO `sys_logininfor` VALUES (125, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-20 01:53:18'); +INSERT INTO `sys_logininfor` VALUES (126, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '退出成功', '2024-08-20 01:54:45'); +INSERT INTO `sys_logininfor` VALUES (127, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-20 01:54:49'); +INSERT INTO `sys_logininfor` VALUES (128, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-20 12:16:31'); +INSERT INTO `sys_logininfor` VALUES (129, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-20 13:07:33'); +INSERT INTO `sys_logininfor` VALUES (130, 'admin', '127.0.0.1', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-08-21 02:37:32'); +INSERT INTO `sys_logininfor` VALUES (131, 'admin', '127.0.0.1', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-08-21 03:14:36'); +INSERT INTO `sys_logininfor` VALUES (132, 'admin', '127.0.0.1', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-08-21 06:08:52'); +INSERT INTO `sys_logininfor` VALUES (133, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-22 03:36:06'); +INSERT INTO `sys_logininfor` VALUES (134, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-22 03:47:06'); +INSERT INTO `sys_logininfor` VALUES (135, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-22 06:36:32'); +INSERT INTO `sys_logininfor` VALUES (136, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-22 06:44:22'); +INSERT INTO `sys_logininfor` VALUES (137, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-22 06:48:14'); +INSERT INTO `sys_logininfor` VALUES (138, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-22 08:09:53'); +INSERT INTO `sys_logininfor` VALUES (139, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-22 08:37:07'); +INSERT INTO `sys_logininfor` VALUES (140, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-22 10:37:38'); +INSERT INTO `sys_logininfor` VALUES (141, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-22 12:05:05'); +INSERT INTO `sys_logininfor` VALUES (142, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-22 12:15:51'); +INSERT INTO `sys_logininfor` VALUES (143, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-23 12:20:22'); +INSERT INTO `sys_logininfor` VALUES (144, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-23 14:07:06'); +INSERT INTO `sys_logininfor` VALUES (145, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '1', '验证码已失效', '2024-08-24 02:40:19'); +INSERT INTO `sys_logininfor` VALUES (146, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-24 02:40:25'); +INSERT INTO `sys_logininfor` VALUES (147, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-24 03:43:54'); +INSERT INTO `sys_logininfor` VALUES (148, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-24 06:32:35'); +INSERT INTO `sys_logininfor` VALUES (149, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '退出成功', '2024-08-24 06:36:05'); +INSERT INTO `sys_logininfor` VALUES (150, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-24 06:36:09'); +INSERT INTO `sys_logininfor` VALUES (151, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-24 07:53:34'); +INSERT INTO `sys_logininfor` VALUES (152, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-25 07:54:03'); +INSERT INTO `sys_logininfor` VALUES (153, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-25 08:31:27'); +INSERT INTO `sys_logininfor` VALUES (154, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-25 12:23:25'); +INSERT INTO `sys_logininfor` VALUES (155, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-26 06:07:27'); +INSERT INTO `sys_logininfor` VALUES (156, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-26 08:40:31'); +INSERT INTO `sys_logininfor` VALUES (157, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-26 09:50:34'); +INSERT INTO `sys_logininfor` VALUES (158, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-26 11:26:27'); +INSERT INTO `sys_logininfor` VALUES (159, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-26 12:07:34'); +INSERT INTO `sys_logininfor` VALUES (160, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-26 14:22:24'); +INSERT INTO `sys_logininfor` VALUES (161, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-26 15:18:25'); +INSERT INTO `sys_logininfor` VALUES (162, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-27 02:17:54'); +INSERT INTO `sys_logininfor` VALUES (163, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-27 03:41:31'); +INSERT INTO `sys_logininfor` VALUES (164, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '1', '验证码错误', '2024-08-27 06:25:06'); +INSERT INTO `sys_logininfor` VALUES (165, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '1', '验证码错误', '2024-08-27 06:25:10'); +INSERT INTO `sys_logininfor` VALUES (166, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-27 06:25:13'); +INSERT INTO `sys_logininfor` VALUES (167, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-27 07:32:00'); +INSERT INTO `sys_logininfor` VALUES (168, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-27 08:39:36'); +INSERT INTO `sys_logininfor` VALUES (169, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-29 06:38:53'); +INSERT INTO `sys_logininfor` VALUES (170, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-29 06:46:34'); +INSERT INTO `sys_logininfor` VALUES (171, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-29 06:51:27'); +INSERT INTO `sys_logininfor` VALUES (172, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-29 07:34:49'); +INSERT INTO `sys_logininfor` VALUES (173, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-29 08:17:29'); +INSERT INTO `sys_logininfor` VALUES (174, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '1', '验证码已失效', '2024-08-30 06:29:43'); +INSERT INTO `sys_logininfor` VALUES (175, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-30 06:29:45'); +INSERT INTO `sys_logininfor` VALUES (176, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-30 07:12:44'); +INSERT INTO `sys_logininfor` VALUES (177, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-30 08:07:00'); +INSERT INTO `sys_logininfor` VALUES (178, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-30 08:53:46'); +INSERT INTO `sys_logininfor` VALUES (179, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-08-31 02:24:01'); +INSERT INTO `sys_logininfor` VALUES (180, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-09-01 02:38:35'); +INSERT INTO `sys_logininfor` VALUES (181, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-09-01 03:15:35'); +INSERT INTO `sys_logininfor` VALUES (182, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-09-01 03:51:04'); +INSERT INTO `sys_logininfor` VALUES (183, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-09-01 06:29:01'); +INSERT INTO `sys_logininfor` VALUES (184, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-09-01 11:47:50'); +INSERT INTO `sys_logininfor` VALUES (185, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-09-02 11:33:09'); +INSERT INTO `sys_logininfor` VALUES (186, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-09-11 16:03:21'); +INSERT INTO `sys_logininfor` VALUES (187, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-09-11 17:25:25'); +INSERT INTO `sys_logininfor` VALUES (188, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-09-11 23:17:18'); +INSERT INTO `sys_logininfor` VALUES (189, 'admin', '172.16.43.100', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-09-12 18:42:50'); +INSERT INTO `sys_logininfor` VALUES (190, 'lisi', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '1', '用户不存在/密码错误', '2024-09-12 18:47:41'); +INSERT INTO `sys_logininfor` VALUES (191, 'admin', '127.0.0.1', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-09-12 18:47:57'); +INSERT INTO `sys_logininfor` VALUES (192, 'admin', '172.16.43.100', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-09-12 18:59:12'); +INSERT INTO `sys_logininfor` VALUES (193, 'admin', '172.16.43.190', '内网IP', 'Chrome 11', 'Windows 10', '0', '登录成功', '2024-09-12 19:26:05'); +INSERT INTO `sys_logininfor` VALUES (194, 'admin', '127.0.0.1', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-03 13:22:01'); +INSERT INTO `sys_logininfor` VALUES (195, 'admin', '127.0.0.1', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-03 13:34:31'); +INSERT INTO `sys_logininfor` VALUES (196, 'admin', '127.0.0.1', '内网IP', 'Chrome 12', 'Windows 10', '0', '登录成功', '2024-10-06 14:45:19'); +INSERT INTO `sys_logininfor` VALUES (197, 'admin', '127.0.0.1', '内网IP', 'Chrome 13', 'Windows 10', '0', '登录成功', '2024-11-03 15:21:21'); +INSERT INTO `sys_logininfor` VALUES (198, 'admin', '127.0.0.1', '内网IP', 'Chrome 13', 'Windows 10', '0', '退出成功', '2024-11-03 15:34:59'); +INSERT INTO `sys_logininfor` VALUES (199, 'admin', '127.0.0.1', '内网IP', 'Chrome 13', 'Windows 10', '0', '登录成功', '2024-11-03 15:35:03'); +INSERT INTO `sys_logininfor` VALUES (200, 'admin', '127.0.0.1', '内网IP', 'Chrome 13', 'Windows 10', '0', '退出成功', '2024-11-03 16:12:11'); +INSERT INTO `sys_logininfor` VALUES (201, 'admin', '127.0.0.1', '内网IP', 'Chrome 13', 'Windows 10', '0', '登录成功', '2024-11-03 16:12:14'); +INSERT INTO `sys_logininfor` VALUES (202, 'admin', '127.0.0.1', '内网IP', 'Chrome 13', 'Windows 10', '0', '登录成功', '2025-02-24 01:47:41'); +INSERT INTO `sys_logininfor` VALUES (203, 'admin', '127.0.0.1', '内网IP', 'Chrome 13', 'Windows 10', '0', '登录成功', '2025-02-24 04:59:06'); +INSERT INTO `sys_logininfor` VALUES (204, 'admin', '127.0.0.1', '内网IP', 'Chrome 13', 'Windows 10', '0', '登录成功', '2025-02-24 07:41:42'); +INSERT INTO `sys_logininfor` VALUES (205, 'admin', '127.0.0.1', '内网IP', 'Chrome 13', 'Windows 10', '0', '登录成功', '2025-02-24 10:16:05'); +INSERT INTO `sys_logininfor` VALUES (206, 'admin', '127.0.0.1', '内网IP', 'Chrome 13', 'Windows 10', '0', '登录成功', '2025-02-24 11:03:25'); +INSERT INTO `sys_logininfor` VALUES (207, 'admin', '127.0.0.1', '内网IP', 'Chrome 13', 'Windows 10', '0', '登录成功', '2025-02-24 11:18:32'); +INSERT INTO `sys_logininfor` VALUES (208, 'admin', '127.0.0.1', '内网IP', 'Chrome 13', 'Windows 10', '0', '登录成功', '2025-02-25 00:41:09'); +INSERT INTO `sys_logininfor` VALUES (209, 'admin', '127.0.0.1', '内网IP', 'Chrome 13', 'Windows 10', '0', '登录成功', '2025-02-25 03:26:40'); +INSERT INTO `sys_logininfor` VALUES (210, 'admin', '127.0.0.1', '内网IP', 'Chrome 13', 'Windows 10', '0', '登录成功', '2025-02-25 10:50:55'); +INSERT INTO `sys_logininfor` VALUES (211, 'admin', '127.0.0.1', '内网IP', 'Chrome 13', 'Windows 10', '0', '登录成功', '2025-02-26 03:00:14'); +INSERT INTO `sys_logininfor` VALUES (212, 'admin', '127.0.0.1', '内网IP', 'Chrome 13', 'Windows 10', '0', '登录成功', '2025-02-27 00:58:05'); +INSERT INTO `sys_logininfor` VALUES (213, 'admin', '127.0.0.1', '内网IP', 'Chrome 13', 'Windows 10', '0', '登录成功', '2025-02-27 08:13:10'); +INSERT INTO `sys_logininfor` VALUES (214, 'admin', '127.0.0.1', '内网IP', 'Chrome 13', 'Windows 10', '1', '验证码错误', '2025-02-27 11:23:59'); +INSERT INTO `sys_logininfor` VALUES (215, 'admin', '127.0.0.1', '内网IP', 'Chrome 13', 'Windows 10', '0', '登录成功', '2025-02-27 11:24:06'); +INSERT INTO `sys_logininfor` VALUES (216, 'admin', '127.0.0.1', '内网IP', 'Chrome 13', 'Windows 10', '0', '登录成功', '2025-02-27 12:18:07'); +INSERT INTO `sys_logininfor` VALUES (217, 'admin', '127.0.0.1', '内网IP', 'Chrome 13', 'Windows 10', '0', '登录成功', '2025-02-28 00:41:50'); +INSERT INTO `sys_logininfor` VALUES (218, 'admin', '127.0.0.1', '内网IP', 'Chrome 13', 'Windows 10', '0', '登录成功', '2025-02-28 08:07:01'); +INSERT INTO `sys_logininfor` VALUES (219, 'admin', '127.0.0.1', '内网IP', 'Chrome 13', 'Windows 10', '0', '登录成功', '2025-02-28 10:51:47'); +INSERT INTO `sys_logininfor` VALUES (220, 'admin', '127.0.0.1', '内网IP', 'Chrome 13', 'Windows 10', '1', '验证码错误', '2025-02-28 10:52:08'); +INSERT INTO `sys_logininfor` VALUES (221, 'admin', '127.0.0.1', '内网IP', 'Chrome 13', 'Windows 10', '0', '登录成功', '2025-02-28 10:52:17'); +INSERT INTO `sys_logininfor` VALUES (222, 'admin', '127.0.0.1', '内网IP', 'Chrome 13', 'Windows 10', '0', '登录成功', '2025-03-02 01:58:31'); + +-- ---------------------------- +-- Table structure for sys_menu +-- ---------------------------- +DROP TABLE IF EXISTS `sys_menu`; +CREATE TABLE `sys_menu` ( + `menu_id` bigint NOT NULL AUTO_INCREMENT COMMENT '菜单ID', + `menu_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '菜单名称', + `parent_id` bigint NULL DEFAULT 0 COMMENT '父菜单ID', + `order_num` int NULL DEFAULT 0 COMMENT '显示顺序', + `path` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '路由地址', + `component` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '组件路径', + `query` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '路由参数', + `route_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '路由名称', + `is_frame` int NULL DEFAULT 1 COMMENT '是否为外链(0是 1否)', + `is_cache` int NULL DEFAULT 0 COMMENT '是否缓存(0缓存 1不缓存)', + `menu_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '菜单类型(M目录 C菜单 F按钮)', + `visible` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '0' COMMENT '菜单状态(0显示 1隐藏)', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '0' COMMENT '菜单状态(0正常 1停用)', + `perms` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '权限标识', + `icon` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '#' COMMENT '菜单图标', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '备注', + PRIMARY KEY (`menu_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 2053 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '菜单权限表' ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of sys_menu +-- ---------------------------- +INSERT INTO `sys_menu` VALUES (1, '系统管理', 0, 6, 'system', NULL, '', '', 1, 0, 'M', '0', '0', '', 'system', 'admin', '2024-08-14 02:48:23', 'admin', '2024-08-29 06:40:54', '系统管理目录'); +INSERT INTO `sys_menu` VALUES (2, '系统监控', 0, 7, 'monitor', NULL, '', '', 1, 0, 'M', '0', '0', '', 'monitor', 'admin', '2024-08-14 02:48:23', 'admin', '2024-08-29 06:41:07', '系统监控目录'); +INSERT INTO `sys_menu` VALUES (3, '系统工具', 0, 8, 'tool', NULL, '', '', 1, 0, 'M', '0', '0', '', 'tool', 'admin', '2024-08-14 02:48:23', 'admin', '2024-08-29 06:41:14', '系统工具目录'); +INSERT INTO `sys_menu` VALUES (4, '若依官网', 0, 4, 'http://ruoyi.vip', NULL, '', '', 0, 0, 'M', '1', '0', '', 'guide', 'admin', '2024-08-14 02:48:23', 'admin', '2024-08-20 01:57:10', '若依官网地址'); +INSERT INTO `sys_menu` VALUES (100, '用户管理', 1, 1, 'user', 'system/user/index', '', '', 1, 0, 'C', '0', '0', 'system:user:list', 'user', 'admin', '2024-08-14 02:48:23', '', NULL, '用户管理菜单'); +INSERT INTO `sys_menu` VALUES (101, '角色管理', 1, 2, 'role', 'system/role/index', '', '', 1, 0, 'C', '0', '0', 'system:role:list', 'peoples', 'admin', '2024-08-14 02:48:23', '', NULL, '角色管理菜单'); +INSERT INTO `sys_menu` VALUES (102, '菜单管理', 1, 3, 'menu', 'system/menu/index', '', '', 1, 0, 'C', '0', '0', 'system:menu:list', 'tree-table', 'admin', '2024-08-14 02:48:23', '', NULL, '菜单管理菜单'); +INSERT INTO `sys_menu` VALUES (103, '部门管理', 1, 4, 'dept', 'system/dept/index', '', '', 1, 0, 'C', '0', '0', 'system:dept:list', 'tree', 'admin', '2024-08-14 02:48:23', '', NULL, '部门管理菜单'); +INSERT INTO `sys_menu` VALUES (104, '岗位管理', 1, 5, 'post', 'system/post/index', '', '', 1, 0, 'C', '0', '0', 'system:post:list', 'post', 'admin', '2024-08-14 02:48:23', '', NULL, '岗位管理菜单'); +INSERT INTO `sys_menu` VALUES (105, '字典管理', 1, 6, 'dict', 'system/dict/index', '', '', 1, 0, 'C', '0', '0', 'system:dict:list', 'dict', 'admin', '2024-08-14 02:48:23', '', NULL, '字典管理菜单'); +INSERT INTO `sys_menu` VALUES (106, '参数设置', 1, 7, 'config', 'system/config/index', '', '', 1, 0, 'C', '0', '0', 'system:config:list', 'edit', 'admin', '2024-08-14 02:48:23', '', NULL, '参数设置菜单'); +INSERT INTO `sys_menu` VALUES (107, '通知公告', 1, 8, 'notice', 'system/notice/index', '', '', 1, 0, 'C', '0', '0', 'system:notice:list', 'message', 'admin', '2024-08-14 02:48:23', '', NULL, '通知公告菜单'); +INSERT INTO `sys_menu` VALUES (108, '日志管理', 1, 9, 'log', '', '', '', 1, 0, 'M', '0', '0', '', 'log', 'admin', '2024-08-14 02:48:23', '', NULL, '日志管理菜单'); +INSERT INTO `sys_menu` VALUES (109, '在线用户', 2, 1, 'online', 'monitor/online/index', '', '', 1, 0, 'C', '0', '0', 'monitor:online:list', 'online', 'admin', '2024-08-14 02:48:23', '', NULL, '在线用户菜单'); +INSERT INTO `sys_menu` VALUES (110, '定时任务', 2, 2, 'job', 'monitor/job/index', '', '', 1, 0, 'C', '0', '0', 'monitor:job:list', 'job', 'admin', '2024-08-14 02:48:23', '', NULL, '定时任务菜单'); +INSERT INTO `sys_menu` VALUES (111, '数据监控', 2, 3, 'druid', 'monitor/druid/index', '', '', 1, 0, 'C', '0', '0', 'monitor:druid:list', 'druid', 'admin', '2024-08-14 02:48:23', '', NULL, '数据监控菜单'); +INSERT INTO `sys_menu` VALUES (112, '服务监控', 2, 4, 'server', 'monitor/server/index', '', '', 1, 0, 'C', '0', '0', 'monitor:server:list', 'server', 'admin', '2024-08-14 02:48:23', '', NULL, '服务监控菜单'); +INSERT INTO `sys_menu` VALUES (113, '缓存监控', 2, 5, 'cache', 'monitor/cache/index', '', '', 1, 0, 'C', '0', '0', 'monitor:cache:list', 'redis', 'admin', '2024-08-14 02:48:23', '', NULL, '缓存监控菜单'); +INSERT INTO `sys_menu` VALUES (114, '缓存列表', 2, 6, 'cacheList', 'monitor/cache/list', '', '', 1, 0, 'C', '0', '0', 'monitor:cache:list', 'redis-list', 'admin', '2024-08-14 02:48:23', '', NULL, '缓存列表菜单'); +INSERT INTO `sys_menu` VALUES (115, '表单构建', 3, 1, 'build', 'tool/build/index', '', '', 1, 0, 'C', '0', '0', 'tool:build:list', 'build', 'admin', '2024-08-14 02:48:23', '', NULL, '表单构建菜单'); +INSERT INTO `sys_menu` VALUES (116, '代码生成', 3, 2, 'gen', 'tool/gen/index', '', '', 1, 0, 'C', '0', '0', 'tool:gen:list', 'code', 'admin', '2024-08-14 02:48:23', '', NULL, '代码生成菜单'); +INSERT INTO `sys_menu` VALUES (117, '系统接口', 3, 3, 'swagger', 'tool/swagger/index', '', '', 1, 0, 'C', '0', '0', 'tool:swagger:list', 'swagger', 'admin', '2024-08-14 02:48:23', '', NULL, '系统接口菜单'); +INSERT INTO `sys_menu` VALUES (500, '操作日志', 108, 1, 'operlog', 'monitor/operlog/index', '', '', 1, 0, 'C', '0', '0', 'monitor:operlog:list', 'form', 'admin', '2024-08-14 02:48:23', '', NULL, '操作日志菜单'); +INSERT INTO `sys_menu` VALUES (501, '登录日志', 108, 2, 'logininfor', 'monitor/logininfor/index', '', '', 1, 0, 'C', '0', '0', 'monitor:logininfor:list', 'logininfor', 'admin', '2024-08-14 02:48:23', '', NULL, '登录日志菜单'); +INSERT INTO `sys_menu` VALUES (1000, '用户查询', 100, 1, '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:query', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1001, '用户新增', 100, 2, '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:add', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1002, '用户修改', 100, 3, '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:edit', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1003, '用户删除', 100, 4, '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:remove', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1004, '用户导出', 100, 5, '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:export', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1005, '用户导入', 100, 6, '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:import', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1006, '重置密码', 100, 7, '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:resetPwd', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1007, '角色查询', 101, 1, '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:query', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1008, '角色新增', 101, 2, '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:add', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1009, '角色修改', 101, 3, '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:edit', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1010, '角色删除', 101, 4, '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:remove', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1011, '角色导出', 101, 5, '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:export', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1012, '菜单查询', 102, 1, '', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:query', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1013, '菜单新增', 102, 2, '', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:add', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1014, '菜单修改', 102, 3, '', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:edit', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1015, '菜单删除', 102, 4, '', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:remove', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1016, '部门查询', 103, 1, '', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:query', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1017, '部门新增', 103, 2, '', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:add', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1018, '部门修改', 103, 3, '', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:edit', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1019, '部门删除', 103, 4, '', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:remove', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1020, '岗位查询', 104, 1, '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:query', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1021, '岗位新增', 104, 2, '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:add', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1022, '岗位修改', 104, 3, '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:edit', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1023, '岗位删除', 104, 4, '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:remove', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1024, '岗位导出', 104, 5, '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:export', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1025, '字典查询', 105, 1, '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:query', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1026, '字典新增', 105, 2, '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:add', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1027, '字典修改', 105, 3, '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:edit', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1028, '字典删除', 105, 4, '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:remove', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1029, '字典导出', 105, 5, '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:export', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1030, '参数查询', 106, 1, '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:query', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1031, '参数新增', 106, 2, '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:add', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1032, '参数修改', 106, 3, '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:edit', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1033, '参数删除', 106, 4, '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:remove', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1034, '参数导出', 106, 5, '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:export', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1035, '公告查询', 107, 1, '#', '', '', '', 1, 0, 'F', '0', '0', 'system:notice:query', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1036, '公告新增', 107, 2, '#', '', '', '', 1, 0, 'F', '0', '0', 'system:notice:add', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1037, '公告修改', 107, 3, '#', '', '', '', 1, 0, 'F', '0', '0', 'system:notice:edit', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1038, '公告删除', 107, 4, '#', '', '', '', 1, 0, 'F', '0', '0', 'system:notice:remove', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1039, '操作查询', 500, 1, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:query', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1040, '操作删除', 500, 2, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:remove', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1041, '日志导出', 500, 3, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:export', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1042, '登录查询', 501, 1, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:query', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1043, '登录删除', 501, 2, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:remove', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1044, '日志导出', 501, 3, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:export', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1045, '账户解锁', 501, 4, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:unlock', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1046, '在线查询', 109, 1, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:online:query', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1047, '批量强退', 109, 2, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:online:batchLogout', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1048, '单条强退', 109, 3, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:online:forceLogout', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1049, '任务查询', 110, 1, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:query', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1050, '任务新增', 110, 2, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:add', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1051, '任务修改', 110, 3, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:edit', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1052, '任务删除', 110, 4, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:remove', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1053, '状态修改', 110, 5, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:changeStatus', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1054, '任务导出', 110, 6, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:export', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1055, '生成查询', 116, 1, '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:query', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1056, '生成修改', 116, 2, '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:edit', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1057, '生成删除', 116, 3, '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:remove', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1058, '导入代码', 116, 4, '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:import', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1059, '预览代码', 116, 5, '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:preview', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1060, '生成代码', 116, 6, '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:code', '#', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (2000, '服务管理', 0, 4, 'nursing', NULL, NULL, '', 1, 0, 'M', '0', '0', '', 'example', 'admin', '2024-08-14 02:59:12', 'admin', '2024-08-29 06:42:37', ''); +INSERT INTO `sys_menu` VALUES (2001, '护理项目', 2000, 1, 'project', 'nursing/project/index', NULL, '', 1, 0, 'C', '0', '0', 'nursing:project:list', 'color', 'admin', '2024-08-14 03:00:15', 'admin', '2025-01-01 14:21:47', '护理项目菜单'); +INSERT INTO `sys_menu` VALUES (2002, '护理项目查询', 2001, 1, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'nursing:project:query', '#', 'admin', '2024-08-14 03:00:15', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (2003, '护理项目新增', 2001, 2, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'nursing:project:add', '#', 'admin', '2024-08-14 03:00:15', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (2004, '护理项目修改', 2001, 3, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'nursing:project:edit', '#', 'admin', '2024-08-14 03:00:15', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (2005, '护理项目删除', 2001, 4, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'nursing:project:remove', '#', 'admin', '2024-08-14 03:00:15', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (2006, '护理项目导出', 2001, 5, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'nursing:project:export', '#', 'admin', '2024-08-14 03:00:15', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (2007, '护理等级', 2000, 3, 'level', 'nursing/level/index', NULL, '', 1, 0, 'C', '0', '0', 'nursing:level:list', 'guide', 'admin', '2024-08-14 08:29:05', 'admin', '2025-01-01 14:22:41', '护理等级菜单'); +INSERT INTO `sys_menu` VALUES (2008, '护理等级查询', 2007, 1, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'nursing:level:query', '#', 'admin', '2024-08-14 08:29:05', 'admin', '2024-10-03 10:47:20', ''); +INSERT INTO `sys_menu` VALUES (2009, '护理等级新增', 2007, 2, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'nursing:level:add', '#', 'admin', '2024-08-14 08:29:05', 'admin', '2024-10-03 10:47:27', ''); +INSERT INTO `sys_menu` VALUES (2010, '护理等级修改', 2007, 3, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'nursing:level:edit', '#', 'admin', '2024-08-14 08:29:05', 'admin', '2024-10-03 10:47:32', ''); +INSERT INTO `sys_menu` VALUES (2011, '护理等级删除', 2007, 4, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'nursing:level:remove', '#', 'admin', '2024-08-14 08:29:05', 'admin', '2024-10-03 10:47:37', ''); +INSERT INTO `sys_menu` VALUES (2012, '护理等级导出', 2007, 5, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'nursing:level:export', '#', 'admin', '2024-08-14 08:29:05', 'admin', '2024-10-03 10:47:42', ''); +INSERT INTO `sys_menu` VALUES (2013, '护理计划', 2000, 2, 'plan', 'nursing/plan/index', NULL, '', 1, 0, 'C', '0', '0', 'nursing:plan:list', 'druid', 'admin', '2024-08-14 08:29:10', 'admin', '2025-01-01 14:22:45', '护理计划菜单'); +INSERT INTO `sys_menu` VALUES (2014, '护理计划查询', 2013, 1, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'nursing:plan:query', '#', 'admin', '2024-08-14 08:29:10', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (2015, '护理计划新增', 2013, 2, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'nursing:plan:add', '#', 'admin', '2024-08-14 08:29:10', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (2016, '护理计划修改', 2013, 3, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'nursing:plan:edit', '#', 'admin', '2024-08-14 08:29:10', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (2017, '护理计划删除', 2013, 4, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'nursing:plan:remove', '#', 'admin', '2024-08-14 08:29:10', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (2018, '护理计划导出', 2013, 5, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'nursing:plan:export', '#', 'admin', '2024-08-14 08:29:10', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (2019, '在住管理', 0, 3, 'liveIn', NULL, NULL, '', 1, 0, 'M', '0', '0', '', 'date-range', 'admin', '2024-08-22 06:49:19', 'admin', '2024-08-29 06:42:27', ''); +INSERT INTO `sys_menu` VALUES (2020, '房型设置', 2019, 0, 'houseSet', 'nursing/roomType/index', NULL, '', 1, 0, 'C', '0', '0', NULL, 'size', 'admin', '2024-08-22 06:50:50', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (2021, '床位预览', 2019, 2, 'floor', 'nursing/floor/index', NULL, '', 1, 0, 'C', '0', '0', NULL, 'tree-table', 'admin', '2024-08-22 08:15:05', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (2022, '入退管理', 0, 2, 'enterQuit', NULL, NULL, '', 1, 0, 'M', '0', '0', '', 'component', 'admin', '2024-08-23 12:52:34', 'admin', '2024-08-29 06:42:15', ''); +INSERT INTO `sys_menu` VALUES (2023, '入住办理', 2022, 2, 'checkIn', 'nursing/checkIn/index', NULL, '', 1, 0, 'C', '0', '0', 'nursing:checkIn:list', 'edit', 'admin', '2024-08-23 13:13:48', 'admin', '2024-11-07 03:10:32', '入住菜单'); +INSERT INTO `sys_menu` VALUES (2024, '入住查询', 2023, 1, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'nursing:checkIn:query', '#', 'admin', '2024-08-23 13:13:48', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (2025, '入住新增', 2023, 2, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'nursing:checkIn:add', '#', 'admin', '2024-08-23 13:13:48', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (2026, '入住修改', 2023, 3, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'nursing:checkIn:edit', '#', 'admin', '2024-08-23 13:13:48', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (2027, '入住删除', 2023, 4, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'nursing:checkIn:remove', '#', 'admin', '2024-08-23 13:13:48', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (2028, '入住导出', 2023, 5, '#', '', NULL, '', 1, 0, 'F', '0', '0', 'nursing:checkIn:export', '#', 'admin', '2024-08-23 13:13:48', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (2035, '入住详情', 2022, 0, 'checkInInfo', 'nursing/checkIn/details', NULL, '', 1, 0, 'C', '1', '0', NULL, 'checkbox', 'admin', '2024-08-24 03:44:48', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (2036, '来访管理', 0, 1, 'appointment', NULL, NULL, '', 1, 0, 'M', '0', '0', NULL, 'button', 'admin', '2024-08-29 06:41:45', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (2037, '智能监测', 0, 5, 'intelligence', NULL, NULL, '', 1, 0, 'M', '0', '0', NULL, 'exit-fullscreen', 'admin', '2024-08-29 06:43:14', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (2038, '预约信息', 2036, 1, 'reservation', 'nursing/reservation/index', NULL, '', 1, 0, 'C', '0', '0', NULL, 'dashboard', 'admin', '2024-08-29 06:47:29', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (2039, '健康评估', 2022, 1, 'healthAssessment', 'nursing/healthAssessment/index', NULL, '', 1, 0, 'C', '0', '0', NULL, 'eye', 'admin', '2024-08-29 06:48:51', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (2040, '评估详情', 2022, 2, 'healthDetails', 'nursing/healthAssessment/details', NULL, '', 1, 0, 'C', '1', '0', '', '#', 'admin', '2024-08-29 06:49:53', 'admin', '2024-08-29 06:50:06', ''); +INSERT INTO `sys_menu` VALUES (2041, '负责老人', 2000, 4, 'oldPeople', 'nursing/oldPeople/index', NULL, '', 1, 0, 'C', '0', '0', '', 'peoples', 'admin', '2024-08-29 06:52:12', 'admin', '2025-01-01 14:22:01', ''); +INSERT INTO `sys_menu` VALUES (2042, '任务安排', 2000, 5, 'arrange', 'nursing/arrange/index', NULL, '', 1, 0, 'C', '0', '0', '', 'redis-list', 'admin', '2024-08-29 06:53:06', 'admin', '2025-01-01 14:22:04', ''); +INSERT INTO `sys_menu` VALUES (2043, '任务安排详情', 2000, 1, 'arrangeDetails', 'nursing/arrange/details', NULL, '', 1, 0, 'C', '1', '0', '', '#', 'admin', '2024-08-29 06:53:37', 'admin', '2024-11-03 14:24:57', ''); +INSERT INTO `sys_menu` VALUES (2044, '设备管理', 2037, 0, 'device', 'nursing/device/index', NULL, '', 1, 0, 'C', '0', '0', '', 'tool', 'admin', '2024-08-29 06:54:54', 'admin', '2024-08-29 07:13:42', ''); +INSERT INTO `sys_menu` VALUES (2045, '设备详情', 2037, 0, 'details', 'nursing/device/details', NULL, '', 1, 0, 'C', '1', '0', NULL, '#', 'admin', '2024-08-29 06:55:25', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (2046, '新增报警规则', 2037, 0, 'ruleDetails', 'nursing/alertRule/details', NULL, '', 1, 0, 'C', '1', '0', NULL, '#', 'admin', '2024-08-29 06:56:01', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (2047, '报警规则', 2037, 1, 'alertRule', 'nursing/alertRule/index', NULL, '', 1, 0, 'C', '0', '0', NULL, 'nested', 'admin', '2024-08-29 06:56:48', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (2048, '报警数据', 2037, 2, 'alertData', 'nursing/alertData/index', NULL, '', 1, 0, 'C', '0', '0', NULL, 'skill', 'admin', '2024-08-29 06:57:25', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (2049, '测试菜单', 0, 10, 'test', NULL, NULL, '', 1, 0, 'M', '0', '1', '', 'message', 'admin', '2024-11-09 01:19:22', 'admin', '2025-02-28 01:17:31', ''); +INSERT INTO `sys_menu` VALUES (2050, '父子组件', 2049, 1, 'parent', 'test/parent', NULL, '', 1, 0, 'C', '0', '0', NULL, 'people', 'admin', '2024-11-09 01:20:42', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (2051, '表单构建', 2049, 2, 'check', 'test/index', NULL, '', 1, 0, 'C', '0', '0', NULL, 'icon', 'admin', '2024-11-09 02:43:49', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (2052, '智能床位', 2019, 3, 'smartBed', 'nursing/smartBed/index', NULL, '', 1, 0, 'C', '0', '0', NULL, 'online', 'admin', '2024-11-15 02:14:10', '', NULL, ''); + +-- ---------------------------- +-- Table structure for sys_notice +-- ---------------------------- +DROP TABLE IF EXISTS `sys_notice`; +CREATE TABLE `sys_notice` ( + `notice_id` int NOT NULL AUTO_INCREMENT COMMENT '公告ID', + `notice_title` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '公告标题', + `notice_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '公告类型(1通知 2公告)', + `notice_content` longblob NULL COMMENT '公告内容', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '0' COMMENT '公告状态(0正常 1关闭)', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`notice_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 10 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '通知公告表' ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of sys_notice +-- ---------------------------- +INSERT INTO `sys_notice` VALUES (1, '温馨提醒:2018-07-01 若依新版本发布啦', '2', 0xE696B0E78988E69CACE58685E5AEB9, '0', 'admin', '2024-08-14 02:48:24', '', NULL, '管理员'); +INSERT INTO `sys_notice` VALUES (2, '维护通知:2018-07-01 若依系统凌晨维护', '1', 0xE7BBB4E68AA4E58685E5AEB9, '0', 'admin', '2024-08-14 02:48:24', '', NULL, '管理员'); + +-- ---------------------------- +-- Table structure for sys_oper_log +-- ---------------------------- +DROP TABLE IF EXISTS `sys_oper_log`; +CREATE TABLE `sys_oper_log` ( + `oper_id` bigint NOT NULL AUTO_INCREMENT COMMENT '日志主键', + `title` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '模块标题', + `business_type` int NULL DEFAULT 0 COMMENT '业务类型(0其它 1新增 2修改 3删除)', + `method` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '方法名称', + `request_method` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '请求方式', + `operator_type` int NULL DEFAULT 0 COMMENT '操作类别(0其它 1后台用户 2手机端用户)', + `oper_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '操作人员', + `dept_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '部门名称', + `oper_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '请求URL', + `oper_ip` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '主机地址', + `oper_location` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '操作地点', + `oper_param` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '请求参数', + `json_result` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '返回参数', + `status` int NULL DEFAULT 0 COMMENT '操作状态(0正常 1异常)', + `error_msg` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '错误消息', + `oper_time` datetime NULL DEFAULT NULL COMMENT '操作时间', + `cost_time` bigint NULL DEFAULT 0 COMMENT '消耗时间', + PRIMARY KEY (`oper_id`) USING BTREE, + INDEX `idx_sys_oper_log_bt`(`business_type` ASC) USING BTREE, + INDEX `idx_sys_oper_log_s`(`status` ASC) USING BTREE, + INDEX `idx_sys_oper_log_ot`(`oper_time` ASC) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 627 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '操作日志记录' ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of sys_oper_log +-- ---------------------------- +INSERT INTO `sys_oper_log` VALUES (100, '代码生成', 6, 'com.ruoyi.generator.controller.GenController.importTableSave()', 'POST', 1, 'admin', '研发部门', '/tool/gen/importTable', '127.0.0.1', '内网IP', '{\"tables\":\"nursing_project\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-14 02:56:15', 107); +INSERT INTO `sys_oper_log` VALUES (101, '代码生成', 2, 'com.ruoyi.generator.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '127.0.0.1', '内网IP', '{\"businessName\":\"project\",\"className\":\"NursingProject\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"编号\",\"columnId\":1,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 02:56:15\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":false,\"isIncrement\":\"1\",\"isInsert\":\"0\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":1,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"Name\",\"columnComment\":\"名称\",\"columnId\":2,\"columnName\":\"name\",\"columnType\":\"varchar(100)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 02:56:15\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"name\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":false,\"sort\":2,\"superColumn\":false,\"tableId\":1,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"OrderNo\",\"columnComment\":\"排序号\",\"columnId\":3,\"columnName\":\"order_no\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 02:56:15\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"0\",\"isRequired\":\"0\",\"javaField\":\"orderNo\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":3,\"superColumn\":false,\"tableId\":1,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"Unit\",\"columnComment\":\"单位\",\"columnId\":4,\"columnName\":\"unit\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 02:56:15\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"0\",\"isRequired\":\"0\",\"javaField\":\"unit\",\"javaType\":\"String\",\"li', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-14 02:57:47', 67); +INSERT INTO `sys_oper_log` VALUES (102, '菜单管理', 1, 'com.ruoyi.web.controller.system.SysMenuController.add()', 'POST', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"createBy\":\"admin\",\"icon\":\"example\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuName\":\"服务管理\",\"menuType\":\"M\",\"orderNum\":1,\"params\":{},\"parentId\":0,\"path\":\"serve\",\"status\":\"0\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-14 02:59:12', 25); +INSERT INTO `sys_oper_log` VALUES (103, '代码生成', 2, 'com.ruoyi.generator.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '127.0.0.1', '内网IP', '{\"businessName\":\"project\",\"className\":\"NursingProject\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"编号\",\"columnId\":1,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 02:56:15\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":false,\"isIncrement\":\"1\",\"isInsert\":\"0\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":1,\"updateBy\":\"\",\"updateTime\":\"2024-08-14 02:57:47\",\"usableColumn\":false},{\"capJavaField\":\"Name\",\"columnComment\":\"名称\",\"columnId\":2,\"columnName\":\"name\",\"columnType\":\"varchar(100)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 02:56:15\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"name\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":false,\"sort\":2,\"superColumn\":false,\"tableId\":1,\"updateBy\":\"\",\"updateTime\":\"2024-08-14 02:57:47\",\"usableColumn\":false},{\"capJavaField\":\"OrderNo\",\"columnComment\":\"排序号\",\"columnId\":3,\"columnName\":\"order_no\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 02:56:15\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"0\",\"isRequired\":\"0\",\"javaField\":\"orderNo\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":3,\"superColumn\":false,\"tableId\":1,\"updateBy\":\"\",\"updateTime\":\"2024-08-14 02:57:47\",\"usableColumn\":false},{\"capJavaField\":\"Unit\",\"columnComment\":\"单位\",\"columnId\":4,\"columnName\":\"unit\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 02:56:15\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInse', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-14 02:59:30', 60); +INSERT INTO `sys_oper_log` VALUES (104, '代码生成', 8, 'com.ruoyi.generator.controller.GenController.batchGenCode()', 'GET', 1, 'admin', '研发部门', '/tool/gen/batchGenCode', '127.0.0.1', '内网IP', '{\"tables\":\"nursing_project\"}', '', 0, '', '2024-08-14 02:59:33', 445); +INSERT INTO `sys_oper_log` VALUES (105, '护理项目', 1, 'com.ruoyi.serve.controller.NursingProjectController.add()', 'POST', 1, 'admin', '研发部门', '/serve/project', '127.0.0.1', '内网IP', '{\"createTime\":\"2024-08-14 11:02:15\",\"id\":84,\"image\":\"/profile/upload/2024/08/14/复建运动@2x_20240814110214A001.png\",\"name\":\"11\",\"nursingRequirement\":\"111\",\"orderNo\":11,\"params\":{},\"price\":1,\"unit\":\"1\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-14 03:02:16', 31); +INSERT INTO `sys_oper_log` VALUES (106, '护理项目', 2, 'com.ruoyi.serve.controller.NursingProjectController.edit()', 'PUT', 1, 'admin', '研发部门', '/serve/project', '127.0.0.1', '内网IP', '{\"createTime\":\"2024-08-14 11:02:16\",\"id\":84,\"image\":\"/profile/upload/2024/08/14/复建运动@2x_20240814110214A001.png\",\"name\":\"222\",\"nursingRequirement\":\"111\",\"orderNo\":2,\"params\":{},\"price\":1,\"status\":1,\"unit\":\"2\",\"updateTime\":\"2024-08-14 11:02:21\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-14 03:02:21', 8); +INSERT INTO `sys_oper_log` VALUES (107, '护理项目', 3, 'com.ruoyi.serve.controller.NursingProjectController.remove()', 'DELETE', 1, 'admin', '研发部门', '/serve/project/84', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-14 03:02:24', 9); +INSERT INTO `sys_oper_log` VALUES (108, '护理项目', 1, 'com.ruoyi.serve.controller.NursingProjectController.add()', 'POST', 1, 'admin', '研发部门', '/serve/project', '127.0.0.1', '内网IP', '{\"createTime\":\"2024-08-14 11:39:59\",\"id\":85,\"image\":\"/profile/upload/2024/08/14/助餐@2x_20240814113958A001.png\",\"name\":\"测试护理项目\",\"nursingRequirement\":\"测试护理项目\",\"orderNo\":1,\"params\":{},\"price\":50,\"unit\":\"元\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-14 03:40:00', 42); +INSERT INTO `sys_oper_log` VALUES (109, '代码生成', 6, 'com.ruoyi.generator.controller.GenController.importTableSave()', 'POST', 1, 'admin', '研发部门', '/tool/gen/importTable', '127.0.0.1', '内网IP', '{\"tables\":\"nursing_level,nursing_plan,nursing_project_plan\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-14 07:37:36', 199); +INSERT INTO `sys_oper_log` VALUES (110, '代码生成', 2, 'com.zzyl.generator.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '127.0.0.1', '内网IP', '{\"businessName\":\"nursingLevel\",\"className\":\"NursingLevel\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键ID\",\"columnId\":14,\"columnName\":\"id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 07:37:35\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":false,\"isIncrement\":\"1\",\"isInsert\":\"0\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"Name\",\"columnComment\":\"等级名称\",\"columnId\":15,\"columnName\":\"name\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 07:37:35\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"name\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"LplanId\",\"columnComment\":\"护理计划ID\",\"columnId\":16,\"columnName\":\"lplan_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 07:37:35\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"0\",\"isRequired\":\"0\",\"javaField\":\"lplanId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":3,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"Fee\",\"columnComment\":\"护理费用\",\"columnId\":17,\"columnName\":\"fee\",\"columnType\":\"decimal(10,2)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 07:37:35\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"0\",\"isRequired\":\"0\",\"javaField\":\"fee\",\"javaType\":\"B', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-14 08:27:28', 108); +INSERT INTO `sys_oper_log` VALUES (111, '代码生成', 2, 'com.zzyl.generator.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '127.0.0.1', '内网IP', '{\"businessName\":\"nursingPlan\",\"className\":\"NursingPlan\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"编号\",\"columnId\":25,\"columnName\":\"id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 07:37:36\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":false,\"isIncrement\":\"1\",\"isInsert\":\"0\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":3,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"SortNo\",\"columnComment\":\"排序号\",\"columnId\":26,\"columnName\":\"sort_no\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 07:37:36\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"0\",\"isRequired\":\"0\",\"javaField\":\"sortNo\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":2,\"superColumn\":false,\"tableId\":3,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"PlanName\",\"columnComment\":\"名称\",\"columnId\":27,\"columnName\":\"plan_name\",\"columnType\":\"varchar(255)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 07:37:36\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"planName\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":3,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"Status\",\"columnComment\":\"状态 0禁用 1启用\",\"columnId\":28,\"columnName\":\"status\",\"columnType\":\"tinyint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 07:37:36\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"radio\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"status\",\"j', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-14 08:28:14', 45); +INSERT INTO `sys_oper_log` VALUES (112, '代码生成', 8, 'com.zzyl.generator.controller.GenController.batchGenCode()', 'GET', 1, 'admin', '研发部门', '/tool/gen/batchGenCode', '127.0.0.1', '内网IP', '{\"tables\":\"nursing_level,nursing_plan\"}', '', 0, '', '2024-08-14 08:28:26', 349); +INSERT INTO `sys_oper_log` VALUES (113, '护理等级', 1, 'com.zzyl.nursing.controller.NursingLevelController.add()', 'POST', 1, 'admin', '研发部门', '/nursing/nursingLevel', '127.0.0.1', '内网IP', '{\"createTime\":\"2024-08-14 16:33:15\",\"description\":\"1223\",\"fee\":100,\"id\":76,\"lplanId\":1,\"name\":\"测试护理等级\",\"params\":{}}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-14 08:33:16', 17); +INSERT INTO `sys_oper_log` VALUES (114, '护理计划', 1, 'com.zzyl.nursing.controller.NursingPlanController.add()', 'POST', 1, 'admin', '研发部门', '/nursing/nursingPlan', '127.0.0.1', '内网IP', '{\"createTime\":\"2024-08-14 16:33:35\",\"id\":129,\"params\":{},\"planName\":\"测试护理等级\",\"sortNo\":1}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-14 08:33:36', 8); +INSERT INTO `sys_oper_log` VALUES (115, '护理项目', 1, 'com.zzyl.nursing.controller.NursingProjectController.add()', 'POST', 1, 'admin', '研发部门', '/serve/project', '127.0.0.1', '内网IP', '{\"createTime\":\"2024-08-18 09:57:59\",\"id\":86,\"image\":\"/profile/upload/2024/08/18/助浴@2x_20240818095758A001.png\",\"name\":\"22\",\"nursingRequirement\":\"22\",\"orderNo\":2,\"params\":{},\"price\":2,\"unit\":\"2\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-18 01:57:59', 20); +INSERT INTO `sys_oper_log` VALUES (116, '护理项目', 2, 'com.zzyl.nursing.controller.NursingProjectController.edit()', 'PUT', 1, 'admin', '研发部门', '/serve/project', '127.0.0.1', '内网IP', '{\"id\":85,\"params\":{},\"status\":1,\"updateTime\":\"2024-08-18 10:14:02\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-18 02:14:03', 5); +INSERT INTO `sys_oper_log` VALUES (117, '护理项目', 2, 'com.zzyl.nursing.controller.NursingProjectController.edit()', 'PUT', 1, 'admin', '研发部门', '/serve/project', '127.0.0.1', '内网IP', '{\"id\":85,\"params\":{},\"status\":0,\"updateTime\":\"2024-08-18 10:14:05\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-18 02:14:05', 4); +INSERT INTO `sys_oper_log` VALUES (118, '护理项目', 2, 'com.zzyl.nursing.controller.NursingProjectController.edit()', 'PUT', 1, 'admin', '研发部门', '/serve/project', '127.0.0.1', '内网IP', '{\"id\":86,\"params\":{},\"status\":0,\"updateTime\":\"2024-08-18 10:14:08\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-18 02:14:08', 3); +INSERT INTO `sys_oper_log` VALUES (119, '护理项目', 2, 'com.zzyl.nursing.controller.NursingProjectController.edit()', 'PUT', 1, 'admin', '研发部门', '/serve/project', '127.0.0.1', '内网IP', '{\"id\":86,\"params\":{},\"status\":1,\"updateTime\":\"2024-08-18 10:14:10\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-18 02:14:10', 5); +INSERT INTO `sys_oper_log` VALUES (120, '字典类型', 1, 'com.zzyl.web.controller.system.SysDictTypeController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/type', '127.0.0.1', '内网IP', '{\"createBy\":\"admin\",\"dictName\":\"护理项目状态\",\"dictType\":\"nursing_project_status\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-18 02:40:48', 11); +INSERT INTO `sys_oper_log` VALUES (121, '字典数据', 1, 'com.zzyl.web.controller.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '127.0.0.1', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"启用\",\"dictSort\":0,\"dictType\":\"nursing_project_status\",\"dictValue\":\"1\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-18 02:41:15', 12); +INSERT INTO `sys_oper_log` VALUES (122, '字典数据', 1, 'com.zzyl.web.controller.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '127.0.0.1', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"禁用\",\"dictSort\":0,\"dictType\":\"nursing_project_status\",\"dictValue\":\"0\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-18 02:41:30', 11); +INSERT INTO `sys_oper_log` VALUES (123, '字典数据', 1, 'com.zzyl.web.controller.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '127.0.0.1', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"其他\",\"dictSort\":0,\"dictType\":\"nursing_project_status\",\"dictValue\":\"2\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-18 02:43:19', 9); +INSERT INTO `sys_oper_log` VALUES (124, '字典类型', 3, 'com.zzyl.web.controller.system.SysDictDataController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/dict/data/102', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-18 02:43:47', 17); +INSERT INTO `sys_oper_log` VALUES (125, '护理项目', 1, 'com.zzyl.nursing.controller.NursingProjectController.add()', 'POST', 1, 'admin', '研发部门', '/serve/project', '127.0.0.1', '内网IP', '{\"createTime\":\"2024-08-18 10:58:31\",\"id\":87,\"image\":\"/profile/upload/2024/08/18/助餐@2x_20240818105812A002.png\",\"name\":\"喂饭\",\"nursingRequirement\":\"无\",\"orderNo\":1,\"params\":{},\"price\":6,\"status\":1,\"unit\":\"元\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-18 02:58:31', 7); +INSERT INTO `sys_oper_log` VALUES (126, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '研发部门', '/nursing/nursingPlan', '127.0.0.1', '内网IP', '{\"id\":129,\"params\":{},\"status\":1,\"updateTime\":\"2024-08-19 10:47:23\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-19 02:47:23', 23); +INSERT INTO `sys_oper_log` VALUES (127, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '研发部门', '/nursing/nursingPlan', '127.0.0.1', '内网IP', '{\"id\":129,\"params\":{},\"status\":1,\"updateTime\":\"2024-08-19 10:47:42\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-19 02:47:42', 5); +INSERT INTO `sys_oper_log` VALUES (128, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '研发部门', '/nursing/nursingPlan', '127.0.0.1', '内网IP', '{\"id\":129,\"params\":{},\"status\":0,\"updateTime\":\"2024-08-19 10:49:01\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-19 02:49:01', 13); +INSERT INTO `sys_oper_log` VALUES (129, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '研发部门', '/nursing/nursingPlan', '127.0.0.1', '内网IP', '{\"id\":129,\"params\":{},\"status\":1,\"updateTime\":\"2024-08-19 10:52:03\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-19 02:52:03', 6); +INSERT INTO `sys_oper_log` VALUES (130, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '研发部门', '/nursing/nursingPlan', '127.0.0.1', '内网IP', '{\"id\":129,\"params\":{},\"status\":0,\"updateTime\":\"2024-08-19 10:52:05\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-19 02:52:05', 5); +INSERT INTO `sys_oper_log` VALUES (131, '护理计划', 1, 'com.zzyl.nursing.controller.NursingPlanController.add()', 'POST', 1, 'admin', '研发部门', '/nursing/nursingPlan', '127.0.0.1', '内网IP', '{\"createTime\":\"2024-08-19 10:53:03\",\"id\":130,\"params\":{},\"planName\":\"6号护理计划\",\"sortNo\":1,\"status\":1}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-19 02:53:03', 6); +INSERT INTO `sys_oper_log` VALUES (132, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '研发部门', '/nursing/nursingPlan', '127.0.0.1', '内网IP', '{\"id\":130,\"params\":{},\"status\":0,\"updateTime\":\"2024-08-19 10:53:13\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-19 02:53:13', 4); +INSERT INTO `sys_oper_log` VALUES (133, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '研发部门', '/nursing/nursingPlan', '127.0.0.1', '内网IP', '{\"id\":130,\"params\":{},\"status\":1,\"updateTime\":\"2024-08-19 10:53:15\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-19 02:53:15', 4); +INSERT INTO `sys_oper_log` VALUES (134, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '研发部门', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":129,\"params\":{},\"status\":1,\"updateTime\":\"2024-08-19 16:47:04\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-19 08:47:04', 11); +INSERT INTO `sys_oper_log` VALUES (135, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '研发部门', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":129,\"params\":{},\"status\":0,\"updateTime\":\"2024-08-19 16:47:06\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-19 08:47:06', 4); +INSERT INTO `sys_oper_log` VALUES (136, '护理计划', 1, 'com.zzyl.nursing.controller.NursingPlanController.add()', 'POST', 1, 'admin', '研发部门', '/nursing/plan', '127.0.0.1', '内网IP', '{\"planName\":\"测试护理计划1\",\"projectPlans\":[{\"executeCycle\":0,\"executeFrequency\":1,\"executeTime\":\"17:11:40\",\"params\":{},\"projectId\":86},{\"executeCycle\":1,\"executeFrequency\":1,\"executeTime\":\"17:11:52\",\"params\":{},\"projectId\":87}],\"sortNo\":1,\"status\":1}', '', 1, '\r\n### Error updating database. Cause: java.sql.SQLException: Field \'create_time\' doesn\'t have a default value\r\n### The error may exist in file [E:\\code\\2024\\zzyl-ruoyi-ai-code\\day02\\zzyl\\zzyl-nursing-platform\\target\\classes\\mapper\\nursing\\NursingPlanMapper.xml]\r\n### The error may involve com.zzyl.nursing.mapper.NursingPlanMapper.insertNursingPlan-Inline\r\n### The error occurred while setting parameters\r\n### SQL: insert into nursing_plan ( sort_no, plan_name, status ) values ( ?, ?, ? )\r\n### Cause: java.sql.SQLException: Field \'create_time\' doesn\'t have a default value\n; Field \'create_time\' doesn\'t have a default value; nested exception is java.sql.SQLException: Field \'create_time\' doesn\'t have a default value', '2024-08-19 09:11:58', 57); +INSERT INTO `sys_oper_log` VALUES (137, '护理计划', 1, 'com.zzyl.nursing.controller.NursingPlanController.add()', 'POST', 1, 'admin', '研发部门', '/nursing/plan', '127.0.0.1', '内网IP', '{\"planName\":\"测试护理计划1\",\"projectPlans\":[{\"executeCycle\":0,\"executeFrequency\":1,\"executeTime\":\"17:11:40\",\"params\":{},\"projectId\":86},{\"executeCycle\":1,\"executeFrequency\":1,\"executeTime\":\"17:11:52\",\"params\":{},\"projectId\":87}],\"sortNo\":1,\"status\":1}', '', 1, '\r\n### Error updating database. Cause: java.sql.SQLException: Field \'create_time\' doesn\'t have a default value\r\n### The error may exist in file [E:\\code\\2024\\zzyl-ruoyi-ai-code\\day02\\zzyl\\zzyl-nursing-platform\\target\\classes\\mapper\\nursing\\NursingPlanMapper.xml]\r\n### The error may involve com.zzyl.nursing.mapper.NursingPlanMapper.insertNursingPlan-Inline\r\n### The error occurred while setting parameters\r\n### SQL: insert into nursing_plan ( sort_no, plan_name, status ) values ( ?, ?, ? )\r\n### Cause: java.sql.SQLException: Field \'create_time\' doesn\'t have a default value\n; Field \'create_time\' doesn\'t have a default value; nested exception is java.sql.SQLException: Field \'create_time\' doesn\'t have a default value', '2024-08-19 09:12:07', 7); +INSERT INTO `sys_oper_log` VALUES (138, '护理计划', 1, 'com.zzyl.nursing.controller.NursingPlanController.add()', 'POST', 1, 'admin', '研发部门', '/nursing/plan', '127.0.0.1', '内网IP', '{\"planName\":\"测试护理计划1\",\"projectPlans\":[{\"executeCycle\":0,\"executeFrequency\":1,\"executeTime\":\"17:11:40\",\"params\":{},\"projectId\":86},{\"executeCycle\":1,\"executeFrequency\":1,\"executeTime\":\"17:11:52\",\"params\":{},\"projectId\":87}],\"sortNo\":1,\"status\":1}', '', 1, '\r\n### Error updating database. Cause: java.sql.SQLIntegrityConstraintViolationException: Column \'create_time\' cannot be null\r\n### The error may exist in file [E:\\code\\2024\\zzyl-ruoyi-ai-code\\day02\\zzyl\\zzyl-nursing-platform\\target\\classes\\mapper\\nursing\\NursingProjectPlanMapper.xml]\r\n### The error may involve defaultParameterMap\r\n### The error occurred while setting parameters\r\n### SQL: INSERT INTO nursing_project_plan (plan_id, project_id, execute_time, execute_cycle, execute_frequency, create_by, update_by, create_time, update_time) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) , (?, ?, ?, ?, ?, ?, ?, ?, ?)\r\n### Cause: java.sql.SQLIntegrityConstraintViolationException: Column \'create_time\' cannot be null\n; Column \'create_time\' cannot be null; nested exception is java.sql.SQLIntegrityConstraintViolationException: Column \'create_time\' cannot be null', '2024-08-19 09:13:23', 303); +INSERT INTO `sys_oper_log` VALUES (139, '护理计划', 1, 'com.zzyl.nursing.controller.NursingPlanController.add()', 'POST', 1, 'admin', '研发部门', '/nursing/plan', '127.0.0.1', '内网IP', '{\"planName\":\"测试护理计划1\",\"projectPlans\":[{\"executeCycle\":0,\"executeFrequency\":1,\"executeTime\":\"17:11:40\",\"params\":{},\"projectId\":86},{\"executeCycle\":1,\"executeFrequency\":1,\"executeTime\":\"17:11:52\",\"params\":{},\"projectId\":87}],\"sortNo\":1,\"status\":1}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-19 09:15:13', 215); +INSERT INTO `sys_oper_log` VALUES (140, '护理计划', 3, 'com.zzyl.nursing.controller.NursingPlanController.remove()', 'DELETE', 1, 'admin', '研发部门', '/nursing/plan/129', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-19 10:58:35', 16); +INSERT INTO `sys_oper_log` VALUES (141, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '研发部门', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":130,\"params\":{},\"status\":0,\"updateTime\":\"2024-08-19 18:58:46\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-19 10:58:46', 15); +INSERT INTO `sys_oper_log` VALUES (142, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '研发部门', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":130,\"params\":{},\"status\":1,\"updateTime\":\"2024-08-19 18:58:48\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-19 10:58:48', 7); +INSERT INTO `sys_oper_log` VALUES (143, '字典类型', 1, 'com.zzyl.web.controller.system.SysDictTypeController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/type', '127.0.0.1', '内网IP', '{\"createBy\":\"admin\",\"dictName\":\"护理计划状态\",\"dictType\":\"nursing_plan_status\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-19 10:59:40', 16); +INSERT INTO `sys_oper_log` VALUES (144, '字典数据', 1, 'com.zzyl.web.controller.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '127.0.0.1', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"启用\",\"dictSort\":0,\"dictType\":\"nursing_plan_status\",\"dictValue\":\"1\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-19 11:00:04', 15); +INSERT INTO `sys_oper_log` VALUES (145, '字典数据', 1, 'com.zzyl.web.controller.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '127.0.0.1', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"禁用\",\"dictSort\":0,\"dictType\":\"nursing_plan_status\",\"dictValue\":\"2\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-19 11:00:10', 15); +INSERT INTO `sys_oper_log` VALUES (146, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '研发部门', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":132,\"planName\":\"测试护理计划1\",\"projectPlans\":[{\"createTime\":\"2024-08-19 09:15:13\",\"executeCycle\":1,\"executeFrequency\":1,\"executeTime\":\"17:11:52\",\"id\":1728,\"params\":{},\"planId\":132,\"projectId\":87}],\"sortNo\":1,\"status\":1}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-19 11:12:59', 36); +INSERT INTO `sys_oper_log` VALUES (147, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '研发部门', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":132,\"planName\":\"测试护理计划1\",\"projectPlans\":[{\"createTime\":\"2024-08-19 09:15:13\",\"executeCycle\":1,\"executeFrequency\":1,\"executeTime\":\"17:11:52\",\"id\":1728,\"params\":{},\"planId\":132,\"projectId\":87}],\"sortNo\":1,\"status\":1}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-19 11:13:15', 11); +INSERT INTO `sys_oper_log` VALUES (148, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '研发部门', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":132,\"planName\":\"测试护理计划1\",\"projectPlans\":[{\"createTime\":\"2024-08-19 11:13:15\",\"executeCycle\":1,\"executeFrequency\":1,\"executeTime\":\"17:11:52\",\"id\":1730,\"params\":{},\"planId\":132,\"projectId\":87}],\"sortNo\":1,\"status\":1}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-19 11:14:48', 71979); +INSERT INTO `sys_oper_log` VALUES (149, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '研发部门', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":132,\"planName\":\"测试护理计划1\",\"projectPlans\":[{\"createTime\":\"2024-08-19 09:15:13\",\"executeCycle\":0,\"executeFrequency\":1,\"executeTime\":\"17:11:40\",\"id\":1727,\"params\":{},\"planId\":132,\"projectId\":86},{\"createTime\":\"2024-08-19 11:14:48\",\"executeCycle\":1,\"executeFrequency\":1,\"executeTime\":\"17:11:52\",\"id\":1731,\"params\":{},\"planId\":132,\"projectId\":87}],\"sortNo\":1,\"status\":1}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-19 11:16:40', 5657); +INSERT INTO `sys_oper_log` VALUES (150, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '研发部门', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":132,\"planName\":\"测试护理计划1\",\"projectPlans\":[{\"createTime\":\"2024-08-19 11:16:40\",\"executeCycle\":1,\"executeFrequency\":1,\"executeTime\":\"17:11:52\",\"id\":1733,\"params\":{},\"planId\":132,\"projectId\":87}],\"sortNo\":1,\"status\":1}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-19 11:16:46', 32); +INSERT INTO `sys_oper_log` VALUES (151, '护理计划', 3, 'com.zzyl.nursing.controller.NursingPlanController.remove()', 'DELETE', 1, 'admin', '研发部门', '/nursing/plan/130', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-19 11:16:58', 8); +INSERT INTO `sys_oper_log` VALUES (152, '护理计划', 3, 'com.zzyl.nursing.controller.NursingPlanController.remove()', 'DELETE', 1, 'admin', '研发部门', '/nursing/plan/132', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-19 11:17:05', 10); +INSERT INTO `sys_oper_log` VALUES (153, '护理计划', 1, 'com.zzyl.nursing.controller.NursingPlanController.add()', 'POST', 1, 'admin', '研发部门', '/nursing/plan', '127.0.0.1', '内网IP', '{\"planName\":\"1号护理计划\",\"projectPlans\":[{\"executeCycle\":1,\"executeFrequency\":7,\"executeTime\":\"19:16:49\",\"params\":{},\"projectId\":87}],\"sortNo\":1,\"status\":1}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-19 11:17:31', 20); +INSERT INTO `sys_oper_log` VALUES (154, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '研发部门', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":133,\"status\":0}', '', 1, 'nested exception is org.apache.ibatis.builder.BuilderException: The expression \'list\' evaluated to a null value.', '2024-08-19 11:17:37', 8); +INSERT INTO `sys_oper_log` VALUES (155, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '研发部门', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":133,\"status\":0}', '', 1, 'nested exception is org.apache.ibatis.builder.BuilderException: The expression \'list\' evaluated to a null value.', '2024-08-19 11:17:45', 5); +INSERT INTO `sys_oper_log` VALUES (156, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '研发部门', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":133,\"status\":0}', '', 1, 'nested exception is org.apache.ibatis.builder.BuilderException: The expression \'list\' evaluated to a null value.', '2024-08-19 11:17:55', 7); +INSERT INTO `sys_oper_log` VALUES (157, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '研发部门', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":133,\"status\":0}', '', 1, '', '2024-08-19 11:27:23', 15); +INSERT INTO `sys_oper_log` VALUES (158, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '研发部门', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":133,\"status\":0}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-19 11:28:24', 2392); +INSERT INTO `sys_oper_log` VALUES (159, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '研发部门', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":133,\"status\":1}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-19 11:28:28', 12); +INSERT INTO `sys_oper_log` VALUES (160, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '研发部门', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":133,\"status\":0}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-19 11:28:30', 16); +INSERT INTO `sys_oper_log` VALUES (161, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '研发部门', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":133,\"status\":1}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-19 11:28:32', 10); +INSERT INTO `sys_oper_log` VALUES (162, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '研发部门', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":133,\"planName\":\"1号护理计划\",\"projectPlans\":[{\"createTime\":\"2024-08-19 11:17:31\",\"executeCycle\":1,\"executeFrequency\":7,\"executeTime\":\"19:16:49\",\"id\":1735,\"params\":{},\"planId\":133,\"projectId\":87},{\"executeCycle\":1,\"executeFrequency\":1,\"executeTime\":\"19:28:34\",\"params\":{},\"projectId\":85}],\"sortNo\":1,\"status\":1}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-19 11:28:43', 19); +INSERT INTO `sys_oper_log` VALUES (163, '护理计划', 1, 'com.zzyl.nursing.controller.NursingPlanController.add()', 'POST', 1, 'admin', '研发部门', '/nursing/plan', '127.0.0.1', '内网IP', '{\"planName\":\"2号护理计划\",\"projectPlans\":[{\"executeCycle\":0,\"executeFrequency\":1,\"executeTime\":\"19:28:45\",\"params\":{},\"projectId\":85}],\"sortNo\":1,\"status\":1}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-19 11:36:10', 34); +INSERT INTO `sys_oper_log` VALUES (164, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '研发部门', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":134,\"status\":0}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-19 11:36:13', 6); +INSERT INTO `sys_oper_log` VALUES (165, '护理项目', 2, 'com.zzyl.nursing.controller.NursingProjectController.edit()', 'PUT', 1, 'admin', '研发部门', '/serve/project', '127.0.0.1', '内网IP', '{\"createTime\":\"2024-08-18 09:57:59\",\"id\":86,\"image\":\"/profile/upload/2024/08/18/助浴@2x_20240818095758A001.png\",\"name\":\"洗衣服\",\"nursingRequirement\":\"22\",\"orderNo\":2,\"params\":{},\"price\":5,\"status\":1,\"unit\":\"元\",\"updateTime\":\"2024-08-19 20:24:49\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-19 12:24:49', 10); +INSERT INTO `sys_oper_log` VALUES (166, '菜单管理', 2, 'com.zzyl.web.controller.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"createTime\":\"2024-08-14 02:48:23\",\"icon\":\"guide\",\"isCache\":\"0\",\"isFrame\":\"0\",\"menuId\":4,\"menuName\":\"若依官网\",\"menuType\":\"M\",\"orderNum\":4,\"params\":{},\"parentId\":0,\"path\":\"http://ruoyi.vip\",\"perms\":\"\",\"query\":\"\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"1\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-20 01:57:10', 20); +INSERT INTO `sys_oper_log` VALUES (167, '护理等级', 2, 'com.zzyl.nursing.controller.NursingLevelController.edit()', 'PUT', 1, 'admin', '研发部门', '/nursing/level', '127.0.0.1', '内网IP', '{\"id\":76,\"params\":{},\"status\":0,\"updateTime\":\"2024-08-20 10:49:50\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-20 02:49:49', 10); +INSERT INTO `sys_oper_log` VALUES (168, '护理等级', 2, 'com.zzyl.nursing.controller.NursingLevelController.edit()', 'PUT', 1, 'admin', '研发部门', '/nursing/level', '127.0.0.1', '内网IP', '{\"id\":76,\"params\":{},\"status\":1,\"updateTime\":\"2024-08-20 10:49:52\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-20 02:49:52', 4); +INSERT INTO `sys_oper_log` VALUES (169, '护理等级', 2, 'com.zzyl.nursing.controller.NursingLevelController.edit()', 'PUT', 1, 'admin', '研发部门', '/nursing/level', '127.0.0.1', '内网IP', '{\"id\":76,\"params\":{},\"status\":0,\"updateTime\":\"2024-08-20 10:55:09\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-20 02:55:09', 24); +INSERT INTO `sys_oper_log` VALUES (170, '护理等级', 2, 'com.zzyl.nursing.controller.NursingLevelController.edit()', 'PUT', 1, 'admin', '研发部门', '/nursing/level', '127.0.0.1', '内网IP', '{\"id\":76,\"params\":{},\"status\":1,\"updateTime\":\"2024-08-20 10:55:11\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-20 02:55:11', 4); +INSERT INTO `sys_oper_log` VALUES (171, '护理等级', 2, 'com.zzyl.nursing.controller.NursingLevelController.edit()', 'PUT', 1, 'admin', '研发部门', '/nursing/level', '127.0.0.1', '内网IP', '{\"id\":76,\"params\":{},\"status\":0,\"updateTime\":\"2024-08-20 10:55:15\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-20 02:55:15', 4); +INSERT INTO `sys_oper_log` VALUES (172, '护理等级', 2, 'com.zzyl.nursing.controller.NursingLevelController.edit()', 'PUT', 1, 'admin', '研发部门', '/nursing/level', '127.0.0.1', '内网IP', '{\"id\":76,\"params\":{},\"status\":1,\"updateTime\":\"2024-08-20 10:55:20\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-20 02:55:20', 6); +INSERT INTO `sys_oper_log` VALUES (173, '护理等级', 2, 'com.zzyl.nursing.controller.NursingLevelController.edit()', 'PUT', 1, 'admin', '研发部门', '/nursing/level', '127.0.0.1', '内网IP', '{\"id\":76,\"params\":{},\"status\":0,\"updateTime\":\"2024-08-20 10:55:23\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-20 02:55:23', 4); +INSERT INTO `sys_oper_log` VALUES (174, '护理等级', 2, 'com.zzyl.nursing.controller.NursingLevelController.edit()', 'PUT', 1, 'admin', '研发部门', '/nursing/level', '127.0.0.1', '内网IP', '{\"id\":76,\"params\":{},\"status\":1,\"updateTime\":\"2024-08-20 11:02:26\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-20 03:02:26', 22); +INSERT INTO `sys_oper_log` VALUES (175, '字典类型', 1, 'com.zzyl.web.controller.system.SysDictTypeController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/type', '127.0.0.1', '内网IP', '{\"createBy\":\"admin\",\"dictName\":\"护理等级状态\",\"dictType\":\"nursing_level_status\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-20 03:04:03', 14); +INSERT INTO `sys_oper_log` VALUES (176, '字典数据', 1, 'com.zzyl.web.controller.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '127.0.0.1', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"启用\",\"dictSort\":0,\"dictType\":\"nursing_level_status\",\"dictValue\":\"1\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-20 03:04:14', 11); +INSERT INTO `sys_oper_log` VALUES (177, '字典数据', 1, 'com.zzyl.web.controller.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '127.0.0.1', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"禁用\",\"dictSort\":0,\"dictType\":\"nursing_level_status\",\"dictValue\":\"0\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-20 03:04:21', 10); +INSERT INTO `sys_oper_log` VALUES (178, '护理等级', 1, 'com.zzyl.nursing.controller.NursingLevelController.add()', 'POST', 1, 'admin', '研发部门', '/nursing/level', '127.0.0.1', '内网IP', '{\"createTime\":\"2024-08-20 11:18:08\",\"description\":\"1223\",\"lplanId\":133,\"name\":\"1号护理计划\",\"params\":{},\"status\":1}', '', 1, '\r\n### Error updating database. Cause: java.sql.SQLException: Field \'fee\' doesn\'t have a default value\r\n### The error may exist in file [E:\\code\\2024\\zzyl-ruoyi-ai-code\\day02\\zzyl\\zzyl-nursing-platform\\target\\classes\\mapper\\nursing\\NursingLevelMapper.xml]\r\n### The error may involve com.zzyl.nursing.mapper.NursingLevelMapper.insertNursingLevel-Inline\r\n### The error occurred while setting parameters\r\n### SQL: insert into nursing_level ( name, lplan_id, status, description, create_time ) values ( ?, ?, ?, ?, ? )\r\n### Cause: java.sql.SQLException: Field \'fee\' doesn\'t have a default value\n; Field \'fee\' doesn\'t have a default value; nested exception is java.sql.SQLException: Field \'fee\' doesn\'t have a default value', '2024-08-20 03:18:08', 58); +INSERT INTO `sys_oper_log` VALUES (179, '护理等级', 1, 'com.zzyl.nursing.controller.NursingLevelController.add()', 'POST', 1, 'admin', '研发部门', '/nursing/level', '127.0.0.1', '内网IP', '{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000,\"id\":77,\"lplanId\":133,\"name\":\"1号护理计划\",\"params\":{},\"status\":1}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-20 03:18:21', 7); +INSERT INTO `sys_oper_log` VALUES (180, '护理等级', 2, 'com.zzyl.nursing.controller.NursingLevelController.edit()', 'PUT', 1, 'admin', '研发部门', '/nursing/level', '127.0.0.1', '内网IP', '{\"id\":77,\"params\":{},\"status\":0,\"updateTime\":\"2024-08-20 11:18:35\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-20 03:18:35', 7); +INSERT INTO `sys_oper_log` VALUES (181, '护理等级', 2, 'com.zzyl.nursing.controller.NursingLevelController.edit()', 'PUT', 1, 'admin', '研发部门', '/nursing/level', '127.0.0.1', '内网IP', '{\"id\":77,\"params\":{},\"status\":1,\"updateTime\":\"2024-08-20 11:18:37\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-20 03:18:37', 5); +INSERT INTO `sys_oper_log` VALUES (182, '护理等级', 2, 'com.zzyl.nursing.controller.NursingLevelController.edit()', 'PUT', 1, 'admin', '研发部门', '/nursing/level', '127.0.0.1', '内网IP', '{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000,\"id\":77,\"lplanId\":134,\"name\":\"1号护理计划\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-20 11:18:45\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-20 03:18:45', 4); +INSERT INTO `sys_oper_log` VALUES (183, '代码生成', 2, 'com.zzyl.generator.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '127.0.0.1', '内网IP', '{\"businessName\":\"projectPlan\",\"className\":\"NursingProjectPlan\",\"columns\":[{\"capJavaField\":\"Id\",\"columnId\":34,\"columnName\":\"id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 07:37:36\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":4,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"PlanId\",\"columnComment\":\"计划id\",\"columnId\":35,\"columnName\":\"plan_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 07:37:36\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"planId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":4,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"ProjectId\",\"columnComment\":\"项目id\",\"columnId\":36,\"columnName\":\"project_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 07:37:36\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"projectId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":4,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"ExecuteTime\",\"columnComment\":\"计划执行时间\",\"columnId\":37,\"columnName\":\"execute_time\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 07:37:36\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"executeTime\",\"javaType\"', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-21 02:39:05', 89); +INSERT INTO `sys_oper_log` VALUES (184, '代码生成', 2, 'com.zzyl.generator.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '127.0.0.1', '内网IP', '{\"businessName\":\"projectPlan\",\"className\":\"NursingProjectPlan\",\"columns\":[{\"capJavaField\":\"Id\",\"columnId\":34,\"columnName\":\"id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 07:37:36\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":4,\"updateBy\":\"\",\"updateTime\":\"2024-08-21 02:39:05\",\"usableColumn\":false},{\"capJavaField\":\"PlanId\",\"columnComment\":\"计划id\",\"columnId\":35,\"columnName\":\"plan_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 07:37:36\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"planId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":4,\"updateBy\":\"\",\"updateTime\":\"2024-08-21 02:39:05\",\"usableColumn\":false},{\"capJavaField\":\"ProjectId\",\"columnComment\":\"项目id\",\"columnId\":36,\"columnName\":\"project_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 07:37:36\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"projectId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":4,\"updateBy\":\"\",\"updateTime\":\"2024-08-21 02:39:05\",\"usableColumn\":false},{\"capJavaField\":\"ExecuteTime\",\"columnComment\":\"计划执行时间\",\"columnId\":37,\"columnName\":\"execute_time\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 07:37:36\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-21 02:39:42', 83); +INSERT INTO `sys_oper_log` VALUES (185, '代码生成', 2, 'com.zzyl.generator.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '127.0.0.1', '内网IP', '{\"businessName\":\"nursingLevel\",\"className\":\"NursingLevel\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键ID\",\"columnId\":14,\"columnName\":\"id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 07:37:35\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":false,\"isIncrement\":\"1\",\"isInsert\":\"0\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-08-14 08:27:28\",\"usableColumn\":false},{\"capJavaField\":\"Name\",\"columnComment\":\"等级名称\",\"columnId\":15,\"columnName\":\"name\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 07:37:35\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"name\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-08-14 08:27:28\",\"usableColumn\":false},{\"capJavaField\":\"LplanId\",\"columnComment\":\"护理计划ID\",\"columnId\":16,\"columnName\":\"lplan_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 07:37:35\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"0\",\"isRequired\":\"0\",\"javaField\":\"lplanId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":3,\"superColumn\":false,\"tableId\":2,\"updateBy\":\"\",\"updateTime\":\"2024-08-14 08:27:28\",\"usableColumn\":false},{\"capJavaField\":\"Fee\",\"columnComment\":\"护理费用\",\"columnId\":17,\"columnName\":\"fee\",\"columnType\":\"decimal(10,2)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 07:37:35\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-21 03:24:12', 212); +INSERT INTO `sys_oper_log` VALUES (186, '代码生成', 2, 'com.zzyl.generator.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '127.0.0.1', '内网IP', '{\"businessName\":\"project\",\"className\":\"NursingProject\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"编号\",\"columnId\":1,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 02:56:15\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":false,\"isIncrement\":\"1\",\"isInsert\":\"0\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":1,\"updateBy\":\"\",\"updateTime\":\"2024-08-14 02:59:29\",\"usableColumn\":false},{\"capJavaField\":\"Name\",\"columnComment\":\"名称\",\"columnId\":2,\"columnName\":\"name\",\"columnType\":\"varchar(100)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 02:56:15\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"name\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":false,\"sort\":2,\"superColumn\":false,\"tableId\":1,\"updateBy\":\"\",\"updateTime\":\"2024-08-14 02:59:29\",\"usableColumn\":false},{\"capJavaField\":\"OrderNo\",\"columnComment\":\"排序号\",\"columnId\":3,\"columnName\":\"order_no\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 02:56:15\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"0\",\"isRequired\":\"0\",\"javaField\":\"orderNo\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":3,\"superColumn\":false,\"tableId\":1,\"updateBy\":\"\",\"updateTime\":\"2024-08-14 02:59:29\",\"usableColumn\":false},{\"capJavaField\":\"Unit\",\"columnComment\":\"单位\",\"columnId\":4,\"columnName\":\"unit\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-14 02:56:15\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInse', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-21 03:44:32', 156); +INSERT INTO `sys_oper_log` VALUES (187, '代码生成', 6, 'com.zzyl.generator.controller.GenController.importTableSave()', 'POST', 1, 'admin', '研发部门', '/tool/gen/importTable', '127.0.0.1', '内网IP', '{\"tables\":\"check_in\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-21 03:46:38', 81); +INSERT INTO `sys_oper_log` VALUES (188, '代码生成', 2, 'com.zzyl.generator.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '127.0.0.1', '内网IP', '{\"businessName\":\"checkIn\",\"className\":\"CheckIn\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"id\",\"columnId\":45,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-21 03:46:38\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":5,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"CheckInCode\",\"columnComment\":\"编号\",\"columnId\":46,\"columnName\":\"check_in_code\",\"columnType\":\"varchar(255)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-21 03:46:38\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"checkInCode\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":5,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"Title\",\"columnComment\":\"标题\",\"columnId\":47,\"columnName\":\"title\",\"columnType\":\"varchar(255)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-21 03:46:38\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"title\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":5,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"ElderId\",\"columnComment\":\"老人id\",\"columnId\":48,\"columnName\":\"elder_id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-21 03:46:38\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"elderId\"', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-21 03:47:35', 70); +INSERT INTO `sys_oper_log` VALUES (189, '菜单管理', 1, 'com.zzyl.web.controller.system.SysMenuController.add()', 'POST', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"createBy\":\"admin\",\"icon\":\"date-range\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuName\":\"在住管理\",\"menuType\":\"M\",\"orderNum\":2,\"params\":{},\"parentId\":0,\"path\":\"liveIn\",\"status\":\"0\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-22 06:49:19', 26); +INSERT INTO `sys_oper_log` VALUES (190, '菜单管理', 1, 'com.zzyl.web.controller.system.SysMenuController.add()', 'POST', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"component\":\"nursing/roomType/index\",\"createBy\":\"admin\",\"icon\":\"size\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuName\":\"房型设置\",\"menuType\":\"C\",\"orderNum\":0,\"params\":{},\"parentId\":2019,\"path\":\"houseSet\",\"status\":\"0\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-22 06:50:50', 9); +INSERT INTO `sys_oper_log` VALUES (191, '房型', 2, 'com.zzyl.nursing.controller.RoomTypeController.edit()', 'PUT', 1, 'admin', '研发部门', '/elder/roomType', '127.0.0.1', '内网IP', '{\"id\":4,\"params\":{},\"status\":0,\"updateBy\":\"1\",\"updateTime\":\"2024-08-22 14:54:22\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-22 06:54:25', 23); +INSERT INTO `sys_oper_log` VALUES (192, '房型', 2, 'com.zzyl.nursing.controller.RoomTypeController.edit()', 'PUT', 1, 'admin', '研发部门', '/elder/roomType', '127.0.0.1', '内网IP', '{\"id\":4,\"params\":{},\"status\":0,\"updateBy\":\"1\",\"updateTime\":\"2024-08-22 14:54:25\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-22 06:54:28', 7); +INSERT INTO `sys_oper_log` VALUES (193, '房型', 2, 'com.zzyl.nursing.controller.RoomTypeController.edit()', 'PUT', 1, 'admin', '研发部门', '/elder/roomType', '127.0.0.1', '内网IP', '{\"id\":4,\"params\":{},\"status\":0,\"updateBy\":\"1\",\"updateTime\":\"2024-08-22 14:54:35\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-22 06:54:38', 6); +INSERT INTO `sys_oper_log` VALUES (194, '房型', 2, 'com.zzyl.nursing.controller.RoomTypeController.edit()', 'PUT', 1, 'admin', '研发部门', '/elder/roomType', '127.0.0.1', '内网IP', '{\"id\":4,\"params\":{},\"status\":0,\"updateBy\":\"1\",\"updateTime\":\"2024-08-22 14:56:59\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-22 06:57:01', 29221); +INSERT INTO `sys_oper_log` VALUES (195, '房型', 2, 'com.zzyl.nursing.controller.RoomTypeController.edit()', 'PUT', 1, 'admin', '研发部门', '/elder/roomType', '127.0.0.1', '内网IP', '{\"id\":4,\"params\":{},\"status\":0,\"updateBy\":\"1\",\"updateTime\":\"2024-08-22 14:58:01\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-22 06:58:04', 4065); +INSERT INTO `sys_oper_log` VALUES (196, '房型', 2, 'com.zzyl.nursing.controller.RoomTypeController.edit()', 'PUT', 1, 'admin', '研发部门', '/elder/roomType', '127.0.0.1', '内网IP', '{\"id\":4,\"params\":{},\"status\":0,\"updateBy\":\"1\",\"updateTime\":\"2024-08-22 16:10:12\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-22 08:10:14', 14); +INSERT INTO `sys_oper_log` VALUES (197, '房型', 2, 'com.zzyl.nursing.controller.RoomTypeController.edit()', 'PUT', 1, 'admin', '研发部门', '/elder/roomType', '127.0.0.1', '内网IP', '{\"id\":4,\"params\":{},\"status\":0,\"updateBy\":\"1\",\"updateTime\":\"2024-08-22 16:10:32\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-22 08:10:35', 10); +INSERT INTO `sys_oper_log` VALUES (198, '房型', 2, 'com.zzyl.nursing.controller.RoomTypeController.edit()', 'PUT', 1, 'admin', '研发部门', '/elder/roomType', '127.0.0.1', '内网IP', '{\"id\":4,\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2024-08-22 16:11:39\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-22 08:11:41', 5); +INSERT INTO `sys_oper_log` VALUES (199, '房型', 2, 'com.zzyl.nursing.controller.RoomTypeController.edit()', 'PUT', 1, 'admin', '研发部门', '/elder/roomType', '127.0.0.1', '内网IP', '{\"id\":4,\"params\":{},\"status\":0,\"updateBy\":\"1\",\"updateTime\":\"2024-08-22 16:11:42\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-22 08:11:44', 5); +INSERT INTO `sys_oper_log` VALUES (200, '房型', 2, 'com.zzyl.nursing.controller.RoomTypeController.edit()', 'PUT', 1, 'admin', '研发部门', '/elder/roomType', '127.0.0.1', '内网IP', '{\"id\":4,\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2024-08-22 16:12:02\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-22 08:12:05', 8); +INSERT INTO `sys_oper_log` VALUES (201, '房型', 2, 'com.zzyl.nursing.controller.RoomTypeController.edit()', 'PUT', 1, 'admin', '研发部门', '/elder/roomType', '127.0.0.1', '内网IP', '{\"id\":4,\"params\":{},\"status\":0,\"updateBy\":\"1\",\"updateTime\":\"2024-08-22 16:12:18\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-22 08:12:21', 7); +INSERT INTO `sys_oper_log` VALUES (202, '房型', 2, 'com.zzyl.nursing.controller.RoomTypeController.edit()', 'PUT', 1, 'admin', '研发部门', '/elder/roomType', '127.0.0.1', '内网IP', '{\"id\":4,\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2024-08-22 16:12:20\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-22 08:12:23', 6); +INSERT INTO `sys_oper_log` VALUES (203, '菜单管理', 1, 'com.zzyl.web.controller.system.SysMenuController.add()', 'POST', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"component\":\"nursing/floor/index\",\"createBy\":\"admin\",\"icon\":\"tree-table\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuName\":\"床位预览\",\"menuType\":\"C\",\"orderNum\":2,\"params\":{},\"parentId\":2019,\"path\":\"floor\",\"status\":\"0\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-22 08:15:05', 14); +INSERT INTO `sys_oper_log` VALUES (204, '楼层', 1, 'com.zzyl.nursing.controller.FloorController.add()', 'POST', 1, 'admin', '研发部门', '/elder/floor', '127.0.0.1', '内网IP', '{\"code\":1,\"createBy\":\"1\",\"createTime\":\"2024-08-22 16:19:50\",\"id\":411,\"name\":\"88\",\"params\":{}}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-22 08:19:53', 13); +INSERT INTO `sys_oper_log` VALUES (205, '楼层', 3, 'com.zzyl.nursing.controller.FloorController.remove()', 'DELETE', 1, 'admin', '研发部门', '/elder/floor/411', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-22 08:29:18', 14); +INSERT INTO `sys_oper_log` VALUES (206, '房间', 1, 'com.zzyl.nursing.controller.RoomController.add()', 'POST', 1, 'admin', '研发部门', '/elder/room', '127.0.0.1', '内网IP', '{\"code\":\"102-2\",\"createBy\":\"1\",\"createTime\":\"2024-08-22 18:49:20\",\"floorId\":406,\"id\":86,\"params\":{},\"sort\":1,\"typeName\":\"豪华单人间\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-22 10:49:23', 13); +INSERT INTO `sys_oper_log` VALUES (207, '房型', 2, 'com.zzyl.nursing.controller.RoomTypeController.edit()', 'PUT', 1, 'admin', '研发部门', '/elder/roomType', '127.0.0.1', '内网IP', '{\"id\":105,\"params\":{},\"status\":0,\"updateBy\":\"1\",\"updateTime\":\"2024-08-22 19:05:25\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-22 11:05:28', 6); +INSERT INTO `sys_oper_log` VALUES (208, '房型', 3, 'com.zzyl.nursing.controller.RoomTypeController.remove()', 'DELETE', 1, 'admin', '研发部门', '/elder/roomType/105', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-22 11:05:30', 6); +INSERT INTO `sys_oper_log` VALUES (209, '房型', 3, 'com.zzyl.nursing.controller.RoomTypeController.remove()', 'DELETE', 1, 'admin', '研发部门', '/elder/roomType/109', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-22 11:05:33', 5); +INSERT INTO `sys_oper_log` VALUES (210, '房型', 3, 'com.zzyl.nursing.controller.RoomTypeController.remove()', 'DELETE', 1, 'admin', '研发部门', '/elder/roomType/114', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-22 11:05:38', 5); +INSERT INTO `sys_oper_log` VALUES (211, '房型', 3, 'com.zzyl.nursing.controller.RoomTypeController.remove()', 'DELETE', 1, 'admin', '研发部门', '/elder/roomType/112', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-22 11:05:41', 5); +INSERT INTO `sys_oper_log` VALUES (212, '房型', 3, 'com.zzyl.nursing.controller.RoomTypeController.remove()', 'DELETE', 1, 'admin', '研发部门', '/elder/roomType/113', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-22 11:05:46', 5); +INSERT INTO `sys_oper_log` VALUES (213, '房型', 3, 'com.zzyl.nursing.controller.RoomTypeController.remove()', 'DELETE', 1, 'admin', '研发部门', '/elder/roomType/111', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-22 11:05:51', 5); +INSERT INTO `sys_oper_log` VALUES (214, '房型', 2, 'com.zzyl.nursing.controller.RoomTypeController.edit()', 'PUT', 1, 'admin', '研发部门', '/elder/roomType', '127.0.0.1', '内网IP', '{\"id\":110,\"params\":{},\"status\":0,\"updateBy\":\"1\",\"updateTime\":\"2024-08-22 19:05:50\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-22 11:05:53', 5); +INSERT INTO `sys_oper_log` VALUES (215, '房型', 2, 'com.zzyl.nursing.controller.RoomTypeController.edit()', 'PUT', 1, 'admin', '研发部门', '/elder/roomType', '127.0.0.1', '内网IP', '{\"id\":110,\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2024-08-22 19:05:52\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-22 11:05:55', 4); +INSERT INTO `sys_oper_log` VALUES (216, '房型', 2, 'com.zzyl.nursing.controller.RoomTypeController.edit()', 'PUT', 1, 'admin', '研发部门', '/elder/roomType', '127.0.0.1', '内网IP', '{\"bedCount\":5,\"createBy\":\"1671403256519078138\",\"createTime\":\"2023-12-27 00:07:07\",\"id\":110,\"introduction\":\"12312312312312312312312312312312312312312312312312\",\"name\":\"测试修改\",\"params\":{},\"photo\":\"https://yjy-slwl-oss.oss-cn-hangzhou.aliyuncs.com/00167193-00f1-49a6-85e5-74dd0b93819e.png\",\"price\":1000,\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2024-08-22 19:05:53\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-22 11:06:10', 9); +INSERT INTO `sys_oper_log` VALUES (217, '房型', 1, 'com.zzyl.nursing.controller.RoomTypeController.add()', 'POST', 1, 'admin', '研发部门', '/elder/roomType', '127.0.0.1', '内网IP', '{\"bedCount\":10,\"createBy\":\"1\",\"createTime\":\"2024-08-22 19:06:33\",\"id\":115,\"introduction\":\"水电费方式\",\"name\":\"测试新增\",\"params\":{},\"photo\":\"https://itheim.oss-cn-beijing.aliyuncs.com/8fe7b29d-fce0-4201-becb-0586e8284a9d.png\",\"price\":3500,\"remark\":\"是否\",\"status\":0}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-22 11:06:36', 7); +INSERT INTO `sys_oper_log` VALUES (218, '房型', 2, 'com.zzyl.nursing.controller.RoomTypeController.edit()', 'PUT', 1, 'admin', '研发部门', '/elder/roomType', '127.0.0.1', '内网IP', '{\"id\":115,\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2024-08-22 19:06:41\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-22 11:06:44', 5); +INSERT INTO `sys_oper_log` VALUES (219, '楼层', 1, 'com.zzyl.nursing.controller.FloorController.add()', 'POST', 1, 'admin', '研发部门', '/elder/floor', '127.0.0.1', '内网IP', '{\"code\":1,\"createBy\":\"1\",\"createTime\":\"2024-08-22 19:06:55\",\"id\":412,\"name\":\"13楼\",\"params\":{}}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-22 11:06:58', 4); +INSERT INTO `sys_oper_log` VALUES (220, '房间', 1, 'com.zzyl.nursing.controller.RoomController.add()', 'POST', 1, 'admin', '研发部门', '/elder/room', '127.0.0.1', '内网IP', '{\"code\":\"1301\",\"createBy\":\"1\",\"createTime\":\"2024-08-22 19:07:05\",\"floorId\":412,\"id\":87,\"params\":{},\"sort\":1,\"typeName\":\"双人套房\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-22 11:07:07', 8); +INSERT INTO `sys_oper_log` VALUES (221, '床位', 1, 'com.zzyl.nursing.controller.BedController.add()', 'POST', 1, 'admin', '研发部门', '/elder/bed', '127.0.0.1', '内网IP', '{\"bedNumber\":\"1301-1\",\"createBy\":\"1\",\"createTime\":\"2024-08-22 19:07:15\",\"id\":197,\"params\":{},\"roomId\":87,\"sort\":1}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-22 11:07:18', 7); +INSERT INTO `sys_oper_log` VALUES (222, '床位', 1, 'com.zzyl.nursing.controller.BedController.add()', 'POST', 1, 'admin', '研发部门', '/elder/bed', '127.0.0.1', '内网IP', '{\"bedNumber\":\"1301-2\",\"createBy\":\"1\",\"createTime\":\"2024-08-22 19:07:22\",\"id\":198,\"params\":{},\"roomId\":87,\"sort\":1}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-22 11:07:25', 4); +INSERT INTO `sys_oper_log` VALUES (223, '床位', 2, 'com.zzyl.nursing.controller.BedController.edit()', 'PUT', 1, 'admin', '研发部门', '/elder/bed', '127.0.0.1', '内网IP', '{\"bedNumber\":\"1301-7\",\"id\":197,\"params\":{},\"roomId\":87,\"sort\":1,\"updateBy\":\"1\",\"updateTime\":\"2024-08-22 19:07:28\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-22 11:07:31', 7); +INSERT INTO `sys_oper_log` VALUES (224, '床位', 3, 'com.zzyl.nursing.controller.BedController.remove()', 'DELETE', 1, 'admin', '研发部门', '/elder/bed/197', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-22 11:07:34', 9); +INSERT INTO `sys_oper_log` VALUES (225, '床位', 3, 'com.zzyl.nursing.controller.BedController.remove()', 'DELETE', 1, 'admin', '研发部门', '/elder/bed/198', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-22 11:07:37', 6); +INSERT INTO `sys_oper_log` VALUES (226, '房间', 2, 'com.zzyl.nursing.controller.RoomController.edit()', 'PUT', 1, 'admin', '研发部门', '/elder/room', '127.0.0.1', '内网IP', '{\"code\":\"1302\",\"id\":87,\"params\":{},\"sort\":1,\"typeName\":\"豪华双人间\",\"updateBy\":\"1\",\"updateTime\":\"2024-08-22 19:07:43\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-22 11:07:46', 6); +INSERT INTO `sys_oper_log` VALUES (227, '房间', 3, 'com.zzyl.nursing.controller.RoomController.remove()', 'DELETE', 1, 'admin', '研发部门', '/elder/room/87', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-22 11:07:52', 6); +INSERT INTO `sys_oper_log` VALUES (228, '楼层', 3, 'com.zzyl.nursing.controller.FloorController.remove()', 'DELETE', 1, 'admin', '研发部门', '/elder/floor/412', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-22 11:07:56', 6); +INSERT INTO `sys_oper_log` VALUES (229, '菜单管理', 2, 'com.zzyl.web.controller.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"component\":\"serve/project/index\",\"createTime\":\"2024-08-14 03:00:15\",\"icon\":\"color\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2001,\"menuName\":\"护理项目\",\"menuType\":\"C\",\"orderNum\":1,\"params\":{},\"parentId\":2000,\"path\":\"project\",\"perms\":\"serve:project:list\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-22 12:16:12', 11); +INSERT INTO `sys_oper_log` VALUES (230, '菜单管理', 2, 'com.zzyl.web.controller.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"component\":\"nursing/nursingLevel/index\",\"createTime\":\"2024-08-14 08:29:05\",\"icon\":\"guide\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2007,\"menuName\":\"护理等级\",\"menuType\":\"C\",\"orderNum\":1,\"params\":{},\"parentId\":2000,\"path\":\"nursingLevel\",\"perms\":\"nursing:nursingLevel:list\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-22 12:16:22', 7); +INSERT INTO `sys_oper_log` VALUES (231, '菜单管理', 2, 'com.zzyl.web.controller.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"component\":\"nursing/nursingPlan/index\",\"createTime\":\"2024-08-14 08:29:10\",\"icon\":\"druid\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2013,\"menuName\":\"护理计划\",\"menuType\":\"C\",\"orderNum\":1,\"params\":{},\"parentId\":2000,\"path\":\"nursingPlan\",\"perms\":\"nursing:nursingPlan:list\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-22 12:16:43', 10); +INSERT INTO `sys_oper_log` VALUES (232, '代码生成', 3, 'com.zzyl.generator.controller.GenController.remove()', 'DELETE', 1, 'admin', '研发部门', '/tool/gen/5', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-23 12:21:12', 41); +INSERT INTO `sys_oper_log` VALUES (233, '代码生成', 3, 'com.zzyl.generator.controller.GenController.remove()', 'DELETE', 1, 'admin', '研发部门', '/tool/gen/4', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-23 12:21:18', 13); +INSERT INTO `sys_oper_log` VALUES (234, '代码生成', 3, 'com.zzyl.generator.controller.GenController.remove()', 'DELETE', 1, 'admin', '研发部门', '/tool/gen/3', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-23 12:21:20', 16); +INSERT INTO `sys_oper_log` VALUES (235, '代码生成', 3, 'com.zzyl.generator.controller.GenController.remove()', 'DELETE', 1, 'admin', '研发部门', '/tool/gen/2', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-23 12:21:22', 12); +INSERT INTO `sys_oper_log` VALUES (236, '代码生成', 3, 'com.zzyl.generator.controller.GenController.remove()', 'DELETE', 1, 'admin', '研发部门', '/tool/gen/1', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-23 12:21:24', 12); +INSERT INTO `sys_oper_log` VALUES (237, '代码生成', 6, 'com.zzyl.generator.controller.GenController.importTableSave()', 'POST', 1, 'admin', '研发部门', '/tool/gen/importTable', '127.0.0.1', '内网IP', '{\"tables\":\"contract,check_in_config,check_in,elder\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-23 12:21:32', 364); +INSERT INTO `sys_oper_log` VALUES (238, '代码生成', 2, 'com.zzyl.generator.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '127.0.0.1', '内网IP', '{\"businessName\":\"checkIn\",\"className\":\"CheckIn\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键ID\",\"columnId\":58,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":6,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"ElderId\",\"columnComment\":\"老人ID\",\"columnId\":59,\"columnName\":\"elder_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"elderId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":6,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"IdNumber\",\"columnComment\":\"身份证号\",\"columnId\":60,\"columnName\":\"id_number\",\"columnType\":\"varchar(18)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"idNumber\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":6,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"StartDate\",\"columnComment\":\"入住开始时间\",\"columnId\":61,\"columnName\":\"start_date\",\"columnType\":\"datetime\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"datetime\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"startD', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-23 12:22:45', 76); +INSERT INTO `sys_oper_log` VALUES (239, '代码生成', 2, 'com.zzyl.generator.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '127.0.0.1', '内网IP', '{\"businessName\":\"checkInConfig\",\"className\":\"CheckInConfig\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键ID\",\"columnId\":72,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":7,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"CheckInId\",\"columnComment\":\"入住表ID\",\"columnId\":73,\"columnName\":\"check_in_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"checkInId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":7,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"CareLevelId\",\"columnComment\":\"护理等级ID\",\"columnId\":74,\"columnName\":\"care_level_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"careLevelId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":7,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"CareLevelName\",\"columnComment\":\"护理等级名称\",\"columnId\":75,\"columnName\":\"care_level_name\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRe', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-23 12:23:31', 81); +INSERT INTO `sys_oper_log` VALUES (240, '代码生成', 2, 'com.zzyl.generator.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '127.0.0.1', '内网IP', '{\"businessName\":\"contract\",\"className\":\"Contract\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键ID\",\"columnId\":90,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":8,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"ElderId\",\"columnComment\":\"老人ID\",\"columnId\":91,\"columnName\":\"elder_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"elderId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":8,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"ContractName\",\"columnComment\":\"合同名称\",\"columnId\":92,\"columnName\":\"contract_name\",\"columnType\":\"varchar(100)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"contractName\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":8,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"ContractNumber\",\"columnComment\":\"合同编号\",\"columnId\":93,\"columnName\":\"contract_number\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-23 12:23:58', 87); +INSERT INTO `sys_oper_log` VALUES (241, '代码生成', 2, 'com.zzyl.generator.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '127.0.0.1', '内网IP', '{\"businessName\":\"elder\",\"className\":\"Elder\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"id\",\"columnId\":111,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":9,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"Name\",\"columnComment\":\"名称\",\"columnId\":112,\"columnName\":\"name\",\"columnType\":\"varchar(255)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"name\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":false,\"sort\":2,\"superColumn\":false,\"tableId\":9,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"Image\",\"columnComment\":\"图片\",\"columnId\":113,\"columnName\":\"image\",\"columnType\":\"varchar(255)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"imageUpload\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"image\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":false,\"sort\":3,\"superColumn\":false,\"tableId\":9,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"IdCardNo\",\"columnComment\":\"身份证号\",\"columnId\":114,\"columnName\":\"id_card_no\",\"columnType\":\"varchar(20)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"idCardNo\",\"ja', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-23 12:24:18', 73); +INSERT INTO `sys_oper_log` VALUES (242, '代码生成', 2, 'com.zzyl.generator.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '127.0.0.1', '内网IP', '{\"businessName\":\"checkIn\",\"className\":\"CheckIn\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键ID\",\"columnId\":58,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":6,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 12:22:45\",\"usableColumn\":false},{\"capJavaField\":\"ElderId\",\"columnComment\":\"老人ID\",\"columnId\":59,\"columnName\":\"elder_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"elderId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":6,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 12:22:45\",\"usableColumn\":false},{\"capJavaField\":\"IdNumber\",\"columnComment\":\"身份证号\",\"columnId\":60,\"columnName\":\"id_number\",\"columnType\":\"varchar(18)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"idNumber\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":6,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 12:22:45\",\"usableColumn\":false},{\"capJavaField\":\"StartDate\",\"columnComment\":\"入住开始时间\",\"columnId\":61,\"columnName\":\"start_date\",\"columnType\":\"datetime\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"datetime\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"i', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-23 12:26:43', 97); +INSERT INTO `sys_oper_log` VALUES (243, '代码生成', 2, 'com.zzyl.generator.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '127.0.0.1', '内网IP', '{\"businessName\":\"checkInConfig\",\"className\":\"CheckInConfig\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键ID\",\"columnId\":72,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":7,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 12:23:31\",\"usableColumn\":false},{\"capJavaField\":\"CheckInId\",\"columnComment\":\"入住表ID\",\"columnId\":73,\"columnName\":\"check_in_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"checkInId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":7,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 12:23:31\",\"usableColumn\":false},{\"capJavaField\":\"CareLevelId\",\"columnComment\":\"护理等级ID\",\"columnId\":74,\"columnName\":\"care_level_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"careLevelId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":7,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 12:23:31\",\"usableColumn\":false},{\"capJavaField\":\"CareLevelName\",\"columnComment\":\"护理等级名称\",\"columnId\":75,\"columnName\":\"care_level_name\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":fals', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-23 12:27:19', 74); +INSERT INTO `sys_oper_log` VALUES (244, '代码生成', 2, 'com.zzyl.generator.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '127.0.0.1', '内网IP', '{\"businessName\":\"contract\",\"className\":\"Contract\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键ID\",\"columnId\":90,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":8,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 12:23:58\",\"usableColumn\":false},{\"capJavaField\":\"ElderId\",\"columnComment\":\"老人ID\",\"columnId\":91,\"columnName\":\"elder_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"elderId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":8,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 12:23:58\",\"usableColumn\":false},{\"capJavaField\":\"ContractName\",\"columnComment\":\"合同名称\",\"columnId\":92,\"columnName\":\"contract_name\",\"columnType\":\"varchar(100)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"contractName\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":8,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 12:23:58\",\"usableColumn\":false},{\"capJavaField\":\"ContractNumber\",\"columnComment\":\"合同编号\",\"columnId\":93,\"columnName\":\"contract_number\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"ins', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-23 12:27:57', 88); +INSERT INTO `sys_oper_log` VALUES (245, '代码生成', 2, 'com.zzyl.generator.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '127.0.0.1', '内网IP', '{\"businessName\":\"elder\",\"className\":\"Elder\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"id\",\"columnId\":111,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":9,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 12:24:18\",\"usableColumn\":false},{\"capJavaField\":\"Name\",\"columnComment\":\"名称\",\"columnId\":112,\"columnName\":\"name\",\"columnType\":\"varchar(255)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"name\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":false,\"sort\":2,\"superColumn\":false,\"tableId\":9,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 12:24:18\",\"usableColumn\":false},{\"capJavaField\":\"Image\",\"columnComment\":\"图片\",\"columnId\":113,\"columnName\":\"image\",\"columnType\":\"varchar(255)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"imageUpload\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"image\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":false,\"sort\":3,\"superColumn\":false,\"tableId\":9,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 12:24:18\",\"usableColumn\":false},{\"capJavaField\":\"IdCardNo\",\"columnComment\":\"身份证号\",\"columnId\":114,\"columnName\":\"id_card_no\",\"columnType\":\"varchar(20)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrem', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-23 12:28:53', 72); +INSERT INTO `sys_oper_log` VALUES (246, '代码生成', 8, 'com.zzyl.generator.controller.GenController.batchGenCode()', 'GET', 1, 'admin', '研发部门', '/tool/gen/batchGenCode', '127.0.0.1', '内网IP', '{\"tables\":\"check_in,check_in_config,contract,elder\"}', '', 0, '', '2024-08-23 12:35:43', 748); +INSERT INTO `sys_oper_log` VALUES (247, '菜单管理', 1, 'com.zzyl.web.controller.system.SysMenuController.add()', 'POST', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"createBy\":\"admin\",\"icon\":\"component\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuName\":\"入退管理\",\"menuType\":\"M\",\"orderNum\":3,\"params\":{},\"parentId\":0,\"path\":\"enterQuit\",\"status\":\"0\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-23 12:52:34', 34); +INSERT INTO `sys_oper_log` VALUES (248, '代码生成', 2, 'com.zzyl.generator.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '127.0.0.1', '内网IP', '{\"businessName\":\"checkIn\",\"className\":\"CheckIn\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键ID\",\"columnId\":58,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":6,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 12:26:43\",\"usableColumn\":false},{\"capJavaField\":\"ElderId\",\"columnComment\":\"老人ID\",\"columnId\":59,\"columnName\":\"elder_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"elderId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":6,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 12:26:43\",\"usableColumn\":false},{\"capJavaField\":\"IdNumber\",\"columnComment\":\"身份证号\",\"columnId\":60,\"columnName\":\"id_number\",\"columnType\":\"varchar(18)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"idNumber\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":6,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 12:26:43\",\"usableColumn\":false},{\"capJavaField\":\"StartDate\",\"columnComment\":\"入住开始时间\",\"columnId\":61,\"columnName\":\"start_date\",\"columnType\":\"datetime\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"datetime\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"i', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-23 12:57:16', 152); +INSERT INTO `sys_oper_log` VALUES (249, '代码生成', 2, 'com.zzyl.generator.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '127.0.0.1', '内网IP', '{\"businessName\":\"contract\",\"className\":\"Contract\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键ID\",\"columnId\":90,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":8,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 12:27:57\",\"usableColumn\":false},{\"capJavaField\":\"ElderId\",\"columnComment\":\"老人ID\",\"columnId\":91,\"columnName\":\"elder_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"elderId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":8,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 12:27:57\",\"usableColumn\":false},{\"capJavaField\":\"ContractName\",\"columnComment\":\"合同名称\",\"columnId\":92,\"columnName\":\"contract_name\",\"columnType\":\"varchar(100)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"contractName\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":8,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 12:27:57\",\"usableColumn\":false},{\"capJavaField\":\"ContractNumber\",\"columnComment\":\"合同编号\",\"columnId\":93,\"columnName\":\"contract_number\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"ins', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-23 12:58:53', 124); +INSERT INTO `sys_oper_log` VALUES (250, '代码生成', 8, 'com.zzyl.generator.controller.GenController.batchGenCode()', 'GET', 1, 'admin', '研发部门', '/tool/gen/batchGenCode', '127.0.0.1', '内网IP', '{\"tables\":\"check_in,check_in_config,contract,elder\"}', '', 0, '', '2024-08-23 13:00:15', 629); +INSERT INTO `sys_oper_log` VALUES (251, '代码生成', 2, 'com.zzyl.generator.controller.GenController.synchDb()', 'GET', 1, 'admin', '研发部门', '/tool/gen/synchDb/check_in', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-23 13:28:23', 157); +INSERT INTO `sys_oper_log` VALUES (252, '代码生成', 2, 'com.zzyl.generator.controller.GenController.synchDb()', 'GET', 1, 'admin', '研发部门', '/tool/gen/synchDb/contract', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-23 13:28:27', 141); +INSERT INTO `sys_oper_log` VALUES (253, '代码生成', 2, 'com.zzyl.generator.controller.GenController.synchDb()', 'GET', 1, 'admin', '研发部门', '/tool/gen/synchDb/check_in_config', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-23 13:28:34', 115); +INSERT INTO `sys_oper_log` VALUES (254, '代码生成', 2, 'com.zzyl.generator.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '127.0.0.1', '内网IP', '{\"businessName\":\"contract\",\"className\":\"Contract\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键ID\",\"columnId\":90,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":8,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 13:28:27\",\"usableColumn\":false},{\"capJavaField\":\"ElderId\",\"columnComment\":\"老人ID\",\"columnId\":91,\"columnName\":\"elder_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"elderId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":8,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 13:28:27\",\"usableColumn\":false},{\"capJavaField\":\"ContractName\",\"columnComment\":\"合同名称\",\"columnId\":92,\"columnName\":\"contract_name\",\"columnType\":\"varchar(100)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"contractName\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":8,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 13:28:27\",\"usableColumn\":false},{\"capJavaField\":\"ContractNumber\",\"columnComment\":\"合同编号\",\"columnId\":93,\"columnName\":\"contract_number\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"ins', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-23 13:29:42', 124); +INSERT INTO `sys_oper_log` VALUES (255, '代码生成', 2, 'com.zzyl.generator.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '127.0.0.1', '内网IP', '{\"businessName\":\"checkInConfig\",\"className\":\"CheckInConfig\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键ID\",\"columnId\":72,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":7,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 13:28:34\",\"usableColumn\":false},{\"capJavaField\":\"CheckInId\",\"columnComment\":\"入住表ID\",\"columnId\":73,\"columnName\":\"check_in_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"checkInId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":7,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 13:28:34\",\"usableColumn\":false},{\"capJavaField\":\"CareLevelId\",\"columnComment\":\"护理等级ID\",\"columnId\":74,\"columnName\":\"care_level_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"careLevelId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":7,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 13:28:34\",\"usableColumn\":false},{\"capJavaField\":\"CareLevelName\",\"columnComment\":\"护理等级名称\",\"columnId\":75,\"columnName\":\"care_level_name\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 12:21:31\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":fals', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-23 13:30:20', 88); +INSERT INTO `sys_oper_log` VALUES (256, '代码生成', 3, 'com.zzyl.generator.controller.GenController.remove()', 'DELETE', 1, 'admin', '研发部门', '/tool/gen/7,6', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-23 13:30:49', 20); +INSERT INTO `sys_oper_log` VALUES (257, '代码生成', 6, 'com.zzyl.generator.controller.GenController.importTableSave()', 'POST', 1, 'admin', '研发部门', '/tool/gen/importTable', '127.0.0.1', '内网IP', '{\"tables\":\"check_in_config,check_in\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-23 13:30:56', 138); +INSERT INTO `sys_oper_log` VALUES (258, '代码生成', 3, 'com.zzyl.generator.controller.GenController.remove()', 'DELETE', 1, 'admin', '研发部门', '/tool/gen/10,11', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-23 13:32:19', 15); +INSERT INTO `sys_oper_log` VALUES (259, '代码生成', 6, 'com.zzyl.generator.controller.GenController.importTableSave()', 'POST', 1, 'admin', '研发部门', '/tool/gen/importTable', '127.0.0.1', '内网IP', '{\"tables\":\"check_in_config,check_in\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-23 13:32:24', 124); +INSERT INTO `sys_oper_log` VALUES (260, '代码生成', 2, 'com.zzyl.generator.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '127.0.0.1', '内网IP', '{\"businessName\":\"checkIn\",\"className\":\"CheckIn\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键ID\",\"columnId\":161,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 13:32:23\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":12,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"ElderId\",\"columnComment\":\"老人ID\",\"columnId\":162,\"columnName\":\"elder_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 13:32:23\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"elderId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":12,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"IdCardNo\",\"columnComment\":\"身份证号\",\"columnId\":163,\"columnName\":\"id_card_no\",\"columnType\":\"char(18)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 13:32:23\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"idCardNo\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":12,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"StartDate\",\"columnComment\":\"入住开始时间\",\"columnId\":164,\"columnName\":\"start_date\",\"columnType\":\"date\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 13:32:23\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"datetime\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"start', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-23 13:33:23', 60); +INSERT INTO `sys_oper_log` VALUES (261, '代码生成', 2, 'com.zzyl.generator.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '127.0.0.1', '内网IP', '{\"businessName\":\"check_in_config\",\"className\":\"CheckInConfig\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键ID\",\"columnId\":175,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 13:32:23\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":13,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"CheckInId\",\"columnComment\":\"入住表ID\",\"columnId\":176,\"columnName\":\"check_in_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 13:32:23\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"checkInId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":13,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"NursingLevelId\",\"columnComment\":\"护理等级ID\",\"columnId\":177,\"columnName\":\"nursing_level_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 13:32:23\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"nursingLevelId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":13,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"NursingLevelName\",\"columnComment\":\"护理等级名称\",\"columnId\":178,\"columnName\":\"nursing_level_name\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 13:32:23\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\"', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-23 13:34:17', 85); +INSERT INTO `sys_oper_log` VALUES (262, '代码生成', 8, 'com.zzyl.generator.controller.GenController.batchGenCode()', 'GET', 1, 'admin', '研发部门', '/tool/gen/batchGenCode', '127.0.0.1', '内网IP', '{\"tables\":\"check_in,check_in_config\"}', '', 0, '', '2024-08-23 13:34:27', 332); +INSERT INTO `sys_oper_log` VALUES (263, '代码生成', 3, 'com.zzyl.generator.controller.GenController.remove()', 'DELETE', 1, 'admin', '研发部门', '/tool/gen/13,12', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-23 14:07:17', 36); +INSERT INTO `sys_oper_log` VALUES (264, '代码生成', 6, 'com.zzyl.generator.controller.GenController.importTableSave()', 'POST', 1, 'admin', '研发部门', '/tool/gen/importTable', '127.0.0.1', '内网IP', '{\"tables\":\"check_in_config,check_in\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-23 14:07:25', 220); +INSERT INTO `sys_oper_log` VALUES (265, '代码生成', 2, 'com.zzyl.generator.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '127.0.0.1', '内网IP', '{\"businessName\":\"checkIn\",\"className\":\"CheckIn\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键ID\",\"columnId\":193,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 14:07:25\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":14,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"ElderName\",\"columnComment\":\"老人姓名\",\"columnId\":194,\"columnName\":\"elder_name\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 14:07:25\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"elderName\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":14,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"ElderId\",\"columnComment\":\"老人ID\",\"columnId\":195,\"columnName\":\"elder_id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 14:07:25\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"elderId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":14,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"IdCardNo\",\"columnComment\":\"身份证号\",\"columnId\":196,\"columnName\":\"id_card_no\",\"columnType\":\"char(18)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 14:07:25\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-23 14:09:15', 103); +INSERT INTO `sys_oper_log` VALUES (266, '代码生成', 2, 'com.zzyl.generator.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '127.0.0.1', '内网IP', '{\"businessName\":\"checkInConfig\",\"className\":\"CheckInConfig\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键ID\",\"columnId\":208,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 14:07:25\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":15,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"CheckInId\",\"columnComment\":\"入住表ID\",\"columnId\":209,\"columnName\":\"check_in_id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 14:07:25\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"checkInId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":15,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"NursingLevelId\",\"columnComment\":\"护理等级ID\",\"columnId\":210,\"columnName\":\"nursing_level_id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 14:07:25\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"nursingLevelId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":15,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"NursingLevelName\",\"columnComment\":\"护理等级名称\",\"columnId\":211,\"columnName\":\"nursing_level_name\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 14:07:25\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"i', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-23 14:10:08', 114); +INSERT INTO `sys_oper_log` VALUES (267, '代码生成', 2, 'com.zzyl.generator.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '127.0.0.1', '内网IP', '{\"businessName\":\"checkIn\",\"className\":\"CheckIn\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键ID\",\"columnId\":193,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 14:07:25\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":14,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 14:09:15\",\"usableColumn\":false},{\"capJavaField\":\"ElderName\",\"columnComment\":\"老人姓名\",\"columnId\":194,\"columnName\":\"elder_name\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 14:07:25\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"elderName\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":14,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 14:09:15\",\"usableColumn\":false},{\"capJavaField\":\"ElderId\",\"columnComment\":\"老人ID\",\"columnId\":195,\"columnName\":\"elder_id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 14:07:25\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"elderId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":14,\"updateBy\":\"\",\"updateTime\":\"2024-08-23 14:09:15\",\"usableColumn\":false},{\"capJavaField\":\"IdCardNo\",\"columnComment\":\"身份证号\",\"columnId\":196,\"columnName\":\"id_card_no\",\"columnType\":\"char(18)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-23 14:07:25\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdi', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-23 14:10:18', 80); +INSERT INTO `sys_oper_log` VALUES (268, '代码生成', 8, 'com.zzyl.generator.controller.GenController.batchGenCode()', 'GET', 1, 'admin', '研发部门', '/tool/gen/batchGenCode', '127.0.0.1', '内网IP', '{\"tables\":\"check_in,check_in_config\"}', '', 0, '', '2024-08-23 14:10:23', 420); +INSERT INTO `sys_oper_log` VALUES (269, '菜单管理', 2, 'com.zzyl.web.controller.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"component\":\"nursing/checkIn/index\",\"createTime\":\"2024-08-23 13:13:48\",\"icon\":\"edit\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2023,\"menuName\":\"入住办理\",\"menuType\":\"C\",\"orderNum\":1,\"params\":{},\"parentId\":2022,\"path\":\"checkIn\",\"perms\":\"nursing:checkIn:list\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-24 02:58:12', 37); +INSERT INTO `sys_oper_log` VALUES (270, '菜单管理', 1, 'com.zzyl.web.controller.system.SysMenuController.add()', 'POST', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"component\":\"nursing/checkIn/details\",\"createBy\":\"admin\",\"icon\":\"checkbox\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuName\":\"入住详情\",\"menuType\":\"C\",\"orderNum\":0,\"params\":{},\"parentId\":2022,\"path\":\"checkInInfo\",\"status\":\"0\",\"visible\":\"1\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-24 03:44:48', 12); +INSERT INTO `sys_oper_log` VALUES (271, '菜单管理', 2, 'com.zzyl.web.controller.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"createTime\":\"2024-08-14 02:48:23\",\"icon\":\"system\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":1,\"menuName\":\"系统管理\",\"menuType\":\"M\",\"orderNum\":6,\"params\":{},\"parentId\":0,\"path\":\"system\",\"perms\":\"\",\"query\":\"\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-29 06:40:54', 20); +INSERT INTO `sys_oper_log` VALUES (272, '菜单管理', 2, 'com.zzyl.web.controller.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"createTime\":\"2024-08-14 02:48:23\",\"icon\":\"monitor\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2,\"menuName\":\"系统监控\",\"menuType\":\"M\",\"orderNum\":7,\"params\":{},\"parentId\":0,\"path\":\"monitor\",\"perms\":\"\",\"query\":\"\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-29 06:41:07', 9); +INSERT INTO `sys_oper_log` VALUES (273, '菜单管理', 2, 'com.zzyl.web.controller.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"createTime\":\"2024-08-14 02:48:23\",\"icon\":\"tool\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":3,\"menuName\":\"系统工具\",\"menuType\":\"M\",\"orderNum\":8,\"params\":{},\"parentId\":0,\"path\":\"tool\",\"perms\":\"\",\"query\":\"\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-29 06:41:14', 10); +INSERT INTO `sys_oper_log` VALUES (274, '菜单管理', 1, 'com.zzyl.web.controller.system.SysMenuController.add()', 'POST', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"createBy\":\"admin\",\"icon\":\"button\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuName\":\"来访管理\",\"menuType\":\"M\",\"orderNum\":1,\"params\":{},\"parentId\":0,\"path\":\"appointment\",\"status\":\"0\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-29 06:41:45', 10); +INSERT INTO `sys_oper_log` VALUES (275, '菜单管理', 2, 'com.zzyl.web.controller.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"createTime\":\"2024-08-23 12:52:34\",\"icon\":\"component\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2022,\"menuName\":\"入退管理\",\"menuType\":\"M\",\"orderNum\":2,\"params\":{},\"parentId\":0,\"path\":\"enterQuit\",\"perms\":\"\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-29 06:42:15', 11); +INSERT INTO `sys_oper_log` VALUES (276, '菜单管理', 2, 'com.zzyl.web.controller.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"createTime\":\"2024-08-22 06:49:19\",\"icon\":\"date-range\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2019,\"menuName\":\"在住管理\",\"menuType\":\"M\",\"orderNum\":3,\"params\":{},\"parentId\":0,\"path\":\"liveIn\",\"perms\":\"\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-29 06:42:27', 9); +INSERT INTO `sys_oper_log` VALUES (277, '菜单管理', 2, 'com.zzyl.web.controller.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"createTime\":\"2024-08-14 02:59:12\",\"icon\":\"example\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2000,\"menuName\":\"服务管理\",\"menuType\":\"M\",\"orderNum\":4,\"params\":{},\"parentId\":0,\"path\":\"serve\",\"perms\":\"\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-29 06:42:37', 11); +INSERT INTO `sys_oper_log` VALUES (278, '菜单管理', 1, 'com.zzyl.web.controller.system.SysMenuController.add()', 'POST', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"createBy\":\"admin\",\"icon\":\"exit-fullscreen\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuName\":\"智能监测\",\"menuType\":\"M\",\"orderNum\":5,\"params\":{},\"parentId\":0,\"path\":\"intelligence\",\"status\":\"0\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-29 06:43:14', 10); +INSERT INTO `sys_oper_log` VALUES (279, '菜单管理', 1, 'com.zzyl.web.controller.system.SysMenuController.add()', 'POST', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"component\":\"nursing/reservation/index\",\"createBy\":\"admin\",\"icon\":\"dashboard\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuName\":\"预约信息\",\"menuType\":\"C\",\"orderNum\":1,\"params\":{},\"parentId\":2036,\"path\":\"reservation\",\"status\":\"0\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-29 06:47:29', 10); +INSERT INTO `sys_oper_log` VALUES (280, '菜单管理', 1, 'com.zzyl.web.controller.system.SysMenuController.add()', 'POST', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"component\":\"nursing/healthAssessment/index\",\"createBy\":\"admin\",\"icon\":\"eye\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuName\":\"健康评估\",\"menuType\":\"C\",\"orderNum\":1,\"params\":{},\"parentId\":2022,\"path\":\"healthAssessment\",\"status\":\"0\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-29 06:48:51', 9); +INSERT INTO `sys_oper_log` VALUES (281, '菜单管理', 1, 'com.zzyl.web.controller.system.SysMenuController.add()', 'POST', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"component\":\"nursing/healthAssessment/details\",\"createBy\":\"admin\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuName\":\"评估详情\",\"menuType\":\"C\",\"orderNum\":2,\"params\":{},\"parentId\":2022,\"path\":\"healthDetails\",\"status\":\"0\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-29 06:49:53', 10); +INSERT INTO `sys_oper_log` VALUES (282, '菜单管理', 2, 'com.zzyl.web.controller.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"component\":\"nursing/healthAssessment/details\",\"createTime\":\"2024-08-29 06:49:53\",\"icon\":\"#\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2040,\"menuName\":\"评估详情\",\"menuType\":\"C\",\"orderNum\":2,\"params\":{},\"parentId\":2022,\"path\":\"healthDetails\",\"perms\":\"\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"1\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-29 06:50:06', 9); +INSERT INTO `sys_oper_log` VALUES (283, '菜单管理', 1, 'com.zzyl.web.controller.system.SysMenuController.add()', 'POST', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"component\":\"nursing/oldPeople/index\",\"createBy\":\"admin\",\"icon\":\"peoples\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuName\":\"负责老师\",\"menuType\":\"C\",\"orderNum\":4,\"params\":{},\"parentId\":2000,\"path\":\"oldPeople\",\"status\":\"0\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-29 06:52:12', 9); +INSERT INTO `sys_oper_log` VALUES (284, '菜单管理', 2, 'com.zzyl.web.controller.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"component\":\"nursing/oldPeople/index\",\"createTime\":\"2024-08-29 06:52:12\",\"icon\":\"peoples\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2041,\"menuName\":\"负责老人\",\"menuType\":\"C\",\"orderNum\":4,\"params\":{},\"parentId\":2000,\"path\":\"oldPeople\",\"perms\":\"\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-29 06:52:23', 8); +INSERT INTO `sys_oper_log` VALUES (285, '菜单管理', 1, 'com.zzyl.web.controller.system.SysMenuController.add()', 'POST', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"component\":\"nursing/arrange/index\",\"createBy\":\"admin\",\"icon\":\"redis-list\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuName\":\"任务安排\",\"menuType\":\"C\",\"orderNum\":5,\"params\":{},\"parentId\":2000,\"path\":\"arrange\",\"status\":\"0\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-29 06:53:06', 8); +INSERT INTO `sys_oper_log` VALUES (286, '菜单管理', 1, 'com.zzyl.web.controller.system.SysMenuController.add()', 'POST', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"component\":\"nursing/arrange/details\",\"createBy\":\"admin\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuName\":\"任务安排详情\",\"menuType\":\"C\",\"orderNum\":1,\"params\":{},\"parentId\":2000,\"path\":\"arrangeDetails\",\"status\":\"0\",\"visible\":\"1\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-29 06:53:37', 11); +INSERT INTO `sys_oper_log` VALUES (287, '菜单管理', 1, 'com.zzyl.web.controller.system.SysMenuController.add()', 'POST', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"component\":\"nursing/device/index\",\"createBy\":\"admin\",\"icon\":\"tool\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuName\":\"设备管理\",\"menuType\":\"C\",\"orderNum\":0,\"params\":{},\"parentId\":2037,\"path\":\"device\",\"status\":\"0\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-29 06:54:54', 8); +INSERT INTO `sys_oper_log` VALUES (288, '菜单管理', 1, 'com.zzyl.web.controller.system.SysMenuController.add()', 'POST', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"component\":\"nursing/device/details\",\"createBy\":\"admin\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuName\":\"设备详情\",\"menuType\":\"C\",\"orderNum\":0,\"params\":{},\"parentId\":2037,\"path\":\"details\",\"status\":\"0\",\"visible\":\"1\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-29 06:55:25', 9); +INSERT INTO `sys_oper_log` VALUES (289, '菜单管理', 1, 'com.zzyl.web.controller.system.SysMenuController.add()', 'POST', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"component\":\"nursing/alertRule/details\",\"createBy\":\"admin\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuName\":\"新增报警规则\",\"menuType\":\"C\",\"orderNum\":0,\"params\":{},\"parentId\":2037,\"path\":\"ruleDetails\",\"status\":\"0\",\"visible\":\"1\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-29 06:56:01', 9); +INSERT INTO `sys_oper_log` VALUES (290, '菜单管理', 1, 'com.zzyl.web.controller.system.SysMenuController.add()', 'POST', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"component\":\"nursing/alertRule/index\",\"createBy\":\"admin\",\"icon\":\"nested\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuName\":\"报警规则\",\"menuType\":\"C\",\"orderNum\":1,\"params\":{},\"parentId\":2037,\"path\":\"alertRule\",\"status\":\"0\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-29 06:56:48', 8); +INSERT INTO `sys_oper_log` VALUES (291, '菜单管理', 1, 'com.zzyl.web.controller.system.SysMenuController.add()', 'POST', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"component\":\"nursing/alertData/index\",\"createBy\":\"admin\",\"icon\":\"skill\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuName\":\"报警数据\",\"menuType\":\"C\",\"orderNum\":2,\"params\":{},\"parentId\":2037,\"path\":\"alertData\",\"status\":\"0\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-29 06:57:25', 30); +INSERT INTO `sys_oper_log` VALUES (292, '菜单管理', 2, 'com.zzyl.web.controller.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"component\":\"nursing/device/index\",\"createTime\":\"2024-08-29 06:54:54\",\"icon\":\"tool\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2044,\"menuName\":\"设备管理\",\"menuType\":\"C\",\"orderNum\":0,\"params\":{},\"parentId\":2037,\"path\":\"device\",\"perms\":\"\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-29 07:13:42', 11); +INSERT INTO `sys_oper_log` VALUES (293, '菜单管理', 2, 'com.zzyl.web.controller.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"component\":\"nursing/contract/index\",\"createTime\":\"2024-08-23 13:13:55\",\"icon\":\"documentation\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2029,\"menuName\":\"合同\",\"menuType\":\"C\",\"orderNum\":1,\"params\":{},\"parentId\":2019,\"path\":\"contract\",\"perms\":\"nursing:contract:list\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-29 07:35:27', 9); +INSERT INTO `sys_oper_log` VALUES (294, '护理项目', 1, 'com.zzyl.nursing.controller.NursingProjectController.add()', 'POST', 1, 'admin', '研发部门', '/serve/project', '127.0.0.1', '内网IP', '{\"createBy\":\"1\",\"createTime\":\"2024-08-29 16:47:36\",\"id\":1825787069131255811,\"image\":\"https://itheim.oss-cn-beijing.aliyuncs.com/2b6c0e57-feda-4029-8cbb-99181674f474.png\",\"name\":\"修剪指甲\",\"orderNo\":1,\"params\":{},\"price\":10,\"status\":1,\"unit\":\"次\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-29 08:46:32', 38); +INSERT INTO `sys_oper_log` VALUES (295, '护理项目', 1, 'com.zzyl.nursing.controller.NursingProjectController.add()', 'POST', 1, 'admin', '研发部门', '/serve/project', '127.0.0.1', '内网IP', '{\"createBy\":\"1\",\"createTime\":\"2024-08-29 16:51:49\",\"id\":1,\"image\":\"https://itheim.oss-cn-beijing.aliyuncs.com/b6631465-1684-41fe-8ccd-0b027cb91e90.png\",\"name\":\"修剪指甲\",\"nursingRequirement\":\"无\",\"orderNo\":1,\"params\":{},\"price\":10,\"status\":1,\"unit\":\"次\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-29 08:50:45', 9); +INSERT INTO `sys_oper_log` VALUES (296, '护理项目', 1, 'com.zzyl.nursing.controller.NursingProjectController.add()', 'POST', 1, 'admin', '研发部门', '/serve/project', '127.0.0.1', '内网IP', '{\"createBy\":\"1\",\"createTime\":\"2024-08-29 16:52:26\",\"id\":2,\"image\":\"https://itheim.oss-cn-beijing.aliyuncs.com/41fc58d3-0627-4fa9-8459-906599aa1efa.png\",\"name\":\"衣物清洁\",\"nursingRequirement\":\"无\",\"orderNo\":1,\"params\":{},\"price\":5,\"status\":1,\"unit\":\"件\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-29 08:51:21', 6); +INSERT INTO `sys_oper_log` VALUES (297, '护理项目', 1, 'com.zzyl.nursing.controller.NursingProjectController.add()', 'POST', 1, 'admin', '研发部门', '/serve/project', '127.0.0.1', '内网IP', '{\"createBy\":\"1\",\"createTime\":\"2024-08-29 16:52:51\",\"id\":3,\"image\":\"https://itheim.oss-cn-beijing.aliyuncs.com/e611fcc9-dc45-49ac-abeb-f2ea99c2cffc.png\",\"name\":\"整理床铺\",\"nursingRequirement\":\"无\",\"orderNo\":1,\"params\":{},\"price\":15,\"status\":1,\"unit\":\"次\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-29 08:51:46', 8); +INSERT INTO `sys_oper_log` VALUES (298, '护理项目', 1, 'com.zzyl.nursing.controller.NursingProjectController.add()', 'POST', 1, 'admin', '研发部门', '/serve/project', '127.0.0.1', '内网IP', '{\"createBy\":\"1\",\"createTime\":\"2024-08-29 16:53:29\",\"id\":4,\"image\":\"https://itheim.oss-cn-beijing.aliyuncs.com/d91ba642-88e5-4c3d-8e50-a681ae3300e5.png\",\"name\":\"助餐\",\"nursingRequirement\":\"无\",\"orderNo\":1,\"params\":{},\"price\":15,\"status\":1,\"unit\":\"餐\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-29 08:52:24', 6); +INSERT INTO `sys_oper_log` VALUES (299, '护理项目', 1, 'com.zzyl.nursing.controller.NursingProjectController.add()', 'POST', 1, 'admin', '研发部门', '/serve/project', '127.0.0.1', '内网IP', '{\"createBy\":\"1\",\"createTime\":\"2024-08-29 16:53:51\",\"id\":5,\"image\":\"https://itheim.oss-cn-beijing.aliyuncs.com/125df948-7646-4fce-b322-1db0a84856e7.png\",\"name\":\"助浴\",\"nursingRequirement\":\"无\",\"orderNo\":1,\"params\":{},\"price\":40,\"status\":1,\"unit\":\"次\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-29 08:52:46', 11); +INSERT INTO `sys_oper_log` VALUES (300, '护理项目', 1, 'com.zzyl.nursing.controller.NursingProjectController.add()', 'POST', 1, 'admin', '研发部门', '/serve/project', '127.0.0.1', '内网IP', '{\"createBy\":\"1\",\"createTime\":\"2024-08-29 16:54:21\",\"id\":6,\"image\":\"https://itheim.oss-cn-beijing.aliyuncs.com/a38883fc-870b-40ff-a256-54ce2fc17af9.png\",\"name\":\"洗头\",\"nursingRequirement\":\"无\",\"orderNo\":1,\"params\":{},\"price\":20,\"status\":1,\"unit\":\"次\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-29 08:53:17', 6); +INSERT INTO `sys_oper_log` VALUES (301, '护理项目', 1, 'com.zzyl.nursing.controller.NursingProjectController.add()', 'POST', 1, 'admin', '研发部门', '/serve/project', '127.0.0.1', '内网IP', '{\"createBy\":\"1\",\"createTime\":\"2024-08-29 16:54:45\",\"id\":7,\"image\":\"https://itheim.oss-cn-beijing.aliyuncs.com/95b0ad37-5d61-4ec2-a961-d6fb691a18f0.png\",\"name\":\"洗脸\",\"nursingRequirement\":\"无\",\"orderNo\":1,\"params\":{},\"price\":15,\"status\":1,\"unit\":\"次\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-29 08:53:40', 6); +INSERT INTO `sys_oper_log` VALUES (302, '护理项目', 1, 'com.zzyl.nursing.controller.NursingProjectController.add()', 'POST', 1, 'admin', '研发部门', '/serve/project', '127.0.0.1', '内网IP', '{\"createBy\":\"1\",\"createTime\":\"2024-08-29 16:55:08\",\"id\":8,\"image\":\"https://itheim.oss-cn-beijing.aliyuncs.com/8437eb2d-3ea5-4eee-9d78-017bc8b3a66e.png\",\"name\":\"洗脚\",\"nursingRequirement\":\"无\",\"orderNo\":1,\"params\":{},\"price\":20,\"status\":1,\"unit\":\"次\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-29 08:54:03', 7); +INSERT INTO `sys_oper_log` VALUES (303, '护理项目', 1, 'com.zzyl.nursing.controller.NursingProjectController.add()', 'POST', 1, 'admin', '研发部门', '/serve/project', '127.0.0.1', '内网IP', '{\"createBy\":\"1\",\"createTime\":\"2024-08-29 16:55:36\",\"id\":9,\"image\":\"https://itheim.oss-cn-beijing.aliyuncs.com/dc004cc2-688c-4d22-8fbc-8e923219a2bd.png\",\"name\":\"心理咨询\",\"nursingRequirement\":\"无\",\"orderNo\":1,\"params\":{},\"price\":80,\"status\":1,\"unit\":\"小时\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-29 08:54:32', 6); +INSERT INTO `sys_oper_log` VALUES (304, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '研发部门', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":134,\"status\":1}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-29 08:54:51', 72); +INSERT INTO `sys_oper_log` VALUES (305, '护理计划', 1, 'com.zzyl.nursing.controller.NursingPlanController.add()', 'POST', 1, 'admin', '研发部门', '/nursing/plan', '127.0.0.1', '内网IP', '{\"planName\":\"3号护理计划\",\"projectPlans\":[{\"executeCycle\":2,\"executeFrequency\":1,\"executeTime\":\"16:55:58\",\"params\":{},\"projectId\":1},{\"executeCycle\":0,\"executeFrequency\":1,\"executeTime\":\"16:56:09\",\"params\":{},\"projectId\":5},{\"executeCycle\":0,\"executeFrequency\":1,\"executeTime\":\"08:00:00\",\"params\":{},\"projectId\":4}],\"sortNo\":1,\"status\":1}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-29 08:55:34', 22); +INSERT INTO `sys_oper_log` VALUES (306, '护理等级', 2, 'com.zzyl.nursing.controller.NursingLevelController.edit()', 'PUT', 1, 'admin', '研发部门', '/nursing/level', '127.0.0.1', '内网IP', '{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000,\"id\":77,\"lplanId\":133,\"name\":\"1号护理计划\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2024-08-29 16:57:05\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-29 08:56:00', 11); +INSERT INTO `sys_oper_log` VALUES (307, '护理等级', 2, 'com.zzyl.nursing.controller.NursingLevelController.edit()', 'PUT', 1, 'admin', '研发部门', '/nursing/level', '127.0.0.1', '内网IP', '{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2024-08-29 16:57:23\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-29 08:56:18', 7); +INSERT INTO `sys_oper_log` VALUES (308, '护理等级', 1, 'com.zzyl.nursing.controller.NursingLevelController.add()', 'POST', 1, 'admin', '研发部门', '/nursing/level', '127.0.0.1', '内网IP', '{\"createBy\":\"1\",\"createTime\":\"2024-08-29 16:57:59\",\"description\":\"无\",\"fee\":3000,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-29 08:56:55', 9); +INSERT INTO `sys_oper_log` VALUES (309, '代码生成', 3, 'com.zzyl.generator.controller.GenController.remove()', 'DELETE', 1, 'admin', '研发部门', '/tool/gen/8,9,14,15', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-30 06:29:55', 38); +INSERT INTO `sys_oper_log` VALUES (310, '代码生成', 6, 'com.zzyl.generator.controller.GenController.importTableSave()', 'POST', 1, 'admin', '研发部门', '/tool/gen/importTable', '127.0.0.1', '内网IP', '{\"tables\":\"health_assessment\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-30 06:38:33', 286); +INSERT INTO `sys_oper_log` VALUES (311, '代码生成', 2, 'com.zzyl.generator.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '127.0.0.1', '内网IP', '{\"businessName\":\"healthAssessment\",\"className\":\"HealthAssessment\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键\",\"columnId\":226,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-08-30 06:38:32\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":16,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"ElderName\",\"columnComment\":\"老人姓名\",\"columnId\":227,\"columnName\":\"elder_name\",\"columnType\":\"varchar(255)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-30 06:38:33\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"elderName\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":false,\"sort\":2,\"superColumn\":false,\"tableId\":16,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"IdCard\",\"columnComment\":\"身份证号\",\"columnId\":228,\"columnName\":\"id_card\",\"columnType\":\"varchar(255)\",\"createBy\":\"admin\",\"createTime\":\"2024-08-30 06:38:33\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"idCard\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":false,\"sort\":3,\"superColumn\":false,\"tableId\":16,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"BirthDate\",\"columnComment\":\"出生日期\",\"columnId\":229,\"columnName\":\"birth_date\",\"columnType\":\"datetime\",\"createBy\":\"admin\",\"createTime\":\"2024-08-30 06:38:33\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"datetime\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\"', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-30 06:40:25', 156); +INSERT INTO `sys_oper_log` VALUES (312, '代码生成', 8, 'com.zzyl.generator.controller.GenController.batchGenCode()', 'GET', 1, 'admin', '研发部门', '/tool/gen/batchGenCode', '127.0.0.1', '内网IP', '{\"tables\":\"health_assessment\"}', '', 0, '', '2024-08-30 06:40:42', 149); +INSERT INTO `sys_oper_log` VALUES (313, '健康评估', 1, 'com.zzyl.nursing.controller.HealthAssessmentController.add()', 'POST', 1, 'admin', '研发部门', '/nursing/healthAssessment', '127.0.0.1', '内网IP', '{\"elderName\":\"李爱过\",\"idCard\":\"130123196712131234\",\"physicalExamInstitution\":\"黑马程序员\",\"physicalReportUrl\":\"https://itheim.oss-cn-beijing.aliyuncs.com/dc6314d8-0b68-414b-8825-053794004f39.pdf\"}', '{\"msg\":\"操作成功\",\"code\":200,\"data\":5}', 0, '', '2024-08-30 07:14:57', 85205); +INSERT INTO `sys_oper_log` VALUES (314, '健康评估', 1, 'com.zzyl.nursing.controller.HealthAssessmentController.add()', 'POST', 1, 'admin', '研发部门', '/nursing/healthAssessment', '127.0.0.1', '内网IP', '{\"elderName\":\"李天龙\",\"idCard\":\"123123194912191235\",\"physicalExamInstitution\":\"黑马\",\"physicalReportUrl\":\"https://itheim.oss-cn-beijing.aliyuncs.com/e6f72807-b17f-4f9b-98c3-71f21a7809fe.pdf\"}', '', 1, 'Request failed: Model ERNIE-4.0-8K-Latest is not supported for chat', '2024-08-30 08:09:45', 96); +INSERT INTO `sys_oper_log` VALUES (315, '健康评估', 1, 'com.zzyl.nursing.controller.HealthAssessmentController.add()', 'POST', 1, 'admin', '研发部门', '/nursing/healthAssessment', '127.0.0.1', '内网IP', '{\"elderName\":\"张芳\",\"idCard\":\"123123194908011235\",\"physicalExamInstitution\":\"黑马\",\"physicalReportUrl\":\"https://itheim.oss-cn-beijing.aliyuncs.com/83aac1e0-e375-4ea0-a7fa-e6ad54c89f67.pdf\"}', '', 1, 'Text \'2023.10.10\' could not be parsed at index 4', '2024-08-30 08:19:50', 119210); +INSERT INTO `sys_oper_log` VALUES (316, '健康评估', 1, 'com.zzyl.nursing.controller.HealthAssessmentController.add()', 'POST', 1, 'admin', '研发部门', '/nursing/healthAssessment', '127.0.0.1', '内网IP', '{\"elderName\":\"张芳\",\"idCard\":\"123192194912151235\",\"physicalExamInstitution\":\"黑马\",\"physicalReportUrl\":\"https://itheim.oss-cn-beijing.aliyuncs.com/0e5b16c3-8ee0-4adb-b0a6-9cc83863ed3a.pdf\"}', '', 1, 'Text \'2023.10.10\' could not be parsed at index 4', '2024-08-30 08:28:44', 114957); +INSERT INTO `sys_oper_log` VALUES (317, '健康评估', 1, 'com.zzyl.nursing.controller.HealthAssessmentController.add()', 'POST', 1, 'admin', '研发部门', '/nursing/healthAssessment', '127.0.0.1', '内网IP', '{\"elderName\":\"张芳\",\"idCard\":\"112123194904081235\",\"physicalExamInstitution\":\"黑马\",\"physicalReportUrl\":\"https://itheim.oss-cn-beijing.aliyuncs.com/3ba497a8-01dc-4e37-80aa-1f0015d2f045.pdf\"}', '{\"msg\":\"操作成功\",\"code\":200,\"data\":6}', 0, '', '2024-08-30 08:58:18', 124963); +INSERT INTO `sys_oper_log` VALUES (318, '健康评估', 1, 'com.zzyl.nursing.controller.HealthAssessmentController.add()', 'POST', 1, 'admin', '研发部门', '/nursing/healthAssessment', '127.0.0.1', '内网IP', '{\"elderName\":\"李天龙\",\"idCard\":\"132123195212190912\",\"physicalExamInstitution\":\"黑马\",\"physicalReportUrl\":\"https://itheim.oss-cn-beijing.aliyuncs.com/29e42721-91f4-4df9-bc7d-d10e7b2f8a95.pdf\"}', '', 1, 'Request failed with api error: {\"error_code\":17,\"error_msg\":\"Open api daily request limit reached\"}', '2024-08-30 09:09:47', 326); +INSERT INTO `sys_oper_log` VALUES (319, '字典类型', 1, 'com.zzyl.web.controller.system.SysDictTypeController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/type', '127.0.0.1', '内网IP', '{\"createBy\":\"admin\",\"dictName\":\"健康评估-入住状态\",\"dictType\":\"admission_status\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-31 03:19:57', 24); +INSERT INTO `sys_oper_log` VALUES (320, '字典数据', 1, 'com.zzyl.web.controller.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '127.0.0.1', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"已入住\",\"dictSort\":0,\"dictType\":\"admission_status\",\"dictValue\":\"0\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-31 03:20:26', 13); +INSERT INTO `sys_oper_log` VALUES (321, '字典数据', 1, 'com.zzyl.web.controller.system.SysDictDataController.add()', 'POST', 1, 'admin', '研发部门', '/system/dict/data', '127.0.0.1', '内网IP', '{\"createBy\":\"admin\",\"default\":false,\"dictLabel\":\"未入住\",\"dictSort\":0,\"dictType\":\"admission_status\",\"dictValue\":\"1\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-08-31 03:20:35', 10); +INSERT INTO `sys_oper_log` VALUES (322, '健康评估', 1, 'com.zzyl.nursing.controller.HealthAssessmentController.add()', 'POST', 1, 'admin', '研发部门', '/nursing/healthAssessment', '127.0.0.1', '内网IP', '{\"elderName\":\"张三\",\"idCard\":\"130123196712131239\",\"physicalExamInstitution\":\"黑马体检\",\"physicalReportUrl\":\"https://itheim.oss-cn-beijing.aliyuncs.com/c4564cc2-ece8-4337-9c3b-95f76eda3ba4.pdf\"}', '', 1, 'Request failed with api error: {\"error_code\":17,\"error_msg\":\"Open api daily request limit reached\"}', '2024-08-31 03:44:12', 322); +INSERT INTO `sys_oper_log` VALUES (323, '健康评估', 1, 'com.zzyl.nursing.controller.HealthAssessmentController.add()', 'POST', 1, 'admin', '研发部门', '/nursing/healthAssessment', '127.0.0.1', '内网IP', '{\"elderName\":\"张三\",\"idCard\":\"130123196712131234\",\"physicalExamInstitution\":\"黑马体检\",\"physicalReportUrl\":\"https://itheim.oss-cn-beijing.aliyuncs.com/142b3c36-6b30-4286-beeb-1d77f53ed306.pdf\"}', '{\"msg\":\"操作成功\",\"code\":200,\"data\":7}', 0, '', '2024-08-31 03:48:56', 114376); +INSERT INTO `sys_oper_log` VALUES (324, '健康评估', 1, 'com.zzyl.nursing.controller.HealthAssessmentController.add()', 'POST', 1, 'admin', '研发部门', '/nursing/healthAssessment', '127.0.0.1', '内网IP', '{\"elderName\":\"罗架构\",\"idCard\":\"132123196012161267\",\"physicalExamInstitution\":\"黑马体检\",\"physicalReportUrl\":\"https://itheim.oss-cn-beijing.aliyuncs.com/1fabebdf-7358-4ac6-8c55-e621b6a410a6.pdf\"}', '{\"msg\":\"操作成功\",\"code\":200,\"data\":8}', 0, '', '2024-09-01 03:20:49', 85938); +INSERT INTO `sys_oper_log` VALUES (325, '健康评估', 1, 'com.zzyl.nursing.controller.HealthAssessmentController.add()', 'POST', 1, 'admin', '研发部门', '/nursing/healthAssessment', '127.0.0.1', '内网IP', '{\"elderName\":\"李天龙\",\"idCard\":\"132123196006121234\",\"physicalExamInstitution\":\"黑马体检\",\"physicalReportUrl\":\"https://itheim.oss-cn-beijing.aliyuncs.com/7b6df8e2-95ce-4df8-b60f-97e1272f6045.pdf\"}', '{\"msg\":\"操作成功\",\"code\":200,\"data\":9}', 0, '', '2024-09-01 11:47:51', 90471); +INSERT INTO `sys_oper_log` VALUES (326, '代码生成', 6, 'com.zzyl.generator.controller.GenController.importTableSave()', 'POST', 1, 'admin', '研发部门', '/tool/gen/importTable', '127.0.0.1', '内网IP', '{\"tables\":\"family_member\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-09-02 11:38:49', 111); +INSERT INTO `sys_oper_log` VALUES (327, '代码生成', 2, 'com.zzyl.generator.controller.GenController.editSave()', 'PUT', 1, 'admin', '研发部门', '/tool/gen', '127.0.0.1', '内网IP', '{\"businessName\":\"member\",\"className\":\"FamilyMember\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键\",\"columnId\":251,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2024-09-02 11:38:49\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":17,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"Phone\",\"columnComment\":\"手机号\",\"columnId\":252,\"columnName\":\"phone\",\"columnType\":\"varchar(20)\",\"createBy\":\"admin\",\"createTime\":\"2024-09-02 11:38:49\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"phone\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":17,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"Name\",\"columnComment\":\"名称\",\"columnId\":253,\"columnName\":\"name\",\"columnType\":\"varchar(100)\",\"createBy\":\"admin\",\"createTime\":\"2024-09-02 11:38:49\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"name\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":false,\"sort\":3,\"superColumn\":false,\"tableId\":17,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"Avatar\",\"columnComment\":\"头像\",\"columnId\":254,\"columnName\":\"avatar\",\"columnType\":\"varchar(255)\",\"createBy\":\"admin\",\"createTime\":\"2024-09-02 11:38:49\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"avatar\",\"javaTyp', '{\"msg\":\"操作成功\",\"code\":200}', 0, '', '2024-09-02 11:39:28', 81); +INSERT INTO `sys_oper_log` VALUES (328, '代码生成', 8, 'com.zzyl.generator.controller.GenController.batchGenCode()', 'GET', 1, 'admin', '研发部门', '/tool/gen/batchGenCode', '127.0.0.1', '内网IP', '{\"tables\":\"family_member\"}', '', 0, '', '2024-09-02 11:39:37', 238); +INSERT INTO `sys_oper_log` VALUES (329, '设备', 2, 'com.zzyl.nursing.controller.DeviceController.edit()', 'PUT', 1, 'admin', '研发部门', '/nursing/device', '172.16.43.100', '内网IP', '{\"bindingLocation\":\"6\",\"deviceDescription\":\"1,4,6\",\"deviceName\":\"xinzengshebei00\",\"id\":202,\"iotId\":\"GDgIaMVb0qzhg2mc9ufTj0rk00\",\"locationType\":1,\"nickname\":\"新增设备001\",\"params\":{},\"physicalLocationType\":2,\"productKey\":\"j0rk0xgSbjY\",\"remark\":\"1楼,104,104-2\",\"updateBy\":\"1\",\"updateTime\":\"2024-09-12 19:00:39\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-09-12 19:00:39', 257); +INSERT INTO `sys_oper_log` VALUES (330, '报警规则', 1, 'com.zzyl.nursing.controller.AlertRuleController.add()', 'POST', 1, 'admin', '研发部门', '/nursing/alertRule', '172.16.43.100', '内网IP', '{\"alertDataType\":0,\"alertEffectivePeriod\":\"00:00:00~23:59:59\",\"alertRuleName\":\"水电费第三方\",\"alertSilentPeriod\":5,\"createBy\":\"1\",\"createTime\":\"2024-09-12 19:05:16\",\"deviceName\":\"watch_08\",\"duration\":1,\"functionId\":\"BatteryPercentage\",\"functionName\":\"用电量\",\"id\":52,\"iotId\":\"TGI9pd72wDbEMvAElvYWj0rk00\",\"moduleId\":\"-1\",\"moduleName\":\"默认模块\",\"operator\":\">=\",\"params\":{},\"productKey\":\"j0rk0xgSbjY\",\"productName\":\"健康定位报警手表\",\"remark\":\"5\",\"status\":1,\"value\":60.0}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-09-12 19:05:16', 11); +INSERT INTO `sys_oper_log` VALUES (331, '报警规则', 3, 'com.zzyl.nursing.controller.AlertRuleController.remove()', 'DELETE', 1, 'admin', '研发部门', '/nursing/alertRule/41', '172.16.43.100', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-09-12 19:05:59', 7); +INSERT INTO `sys_oper_log` VALUES (332, '报警规则', 3, 'com.zzyl.nursing.controller.AlertRuleController.remove()', 'DELETE', 1, 'admin', '研发部门', '/nursing/alertRule/40', '172.16.43.100', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-09-12 19:06:01', 3); +INSERT INTO `sys_oper_log` VALUES (333, '报警规则', 3, 'com.zzyl.nursing.controller.AlertRuleController.remove()', 'DELETE', 1, 'admin', '研发部门', '/nursing/alertRule/39', '172.16.43.100', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-09-12 19:06:04', 4); +INSERT INTO `sys_oper_log` VALUES (334, '报警规则', 3, 'com.zzyl.nursing.controller.AlertRuleController.remove()', 'DELETE', 1, 'admin', '研发部门', '/nursing/alertRule/38', '172.16.43.100', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-09-12 19:06:06', 3); +INSERT INTO `sys_oper_log` VALUES (335, '报警规则', 3, 'com.zzyl.nursing.controller.AlertRuleController.remove()', 'DELETE', 1, 'admin', '研发部门', '/nursing/alertRule/36', '172.16.43.100', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-09-12 19:06:08', 4); +INSERT INTO `sys_oper_log` VALUES (336, '报警规则', 3, 'com.zzyl.nursing.controller.AlertRuleController.remove()', 'DELETE', 1, 'admin', '研发部门', '/nursing/alertRule/35', '172.16.43.100', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-09-12 19:06:10', 4); +INSERT INTO `sys_oper_log` VALUES (337, '报警规则', 3, 'com.zzyl.nursing.controller.AlertRuleController.remove()', 'DELETE', 1, 'admin', '研发部门', '/nursing/alertRule/34', '172.16.43.100', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-09-12 19:06:13', 3); +INSERT INTO `sys_oper_log` VALUES (338, '报警规则', 3, 'com.zzyl.nursing.controller.AlertRuleController.remove()', 'DELETE', 1, 'admin', '研发部门', '/nursing/alertRule/33', '172.16.43.100', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-09-12 19:06:15', 3); +INSERT INTO `sys_oper_log` VALUES (339, '报警规则', 3, 'com.zzyl.nursing.controller.AlertRuleController.remove()', 'DELETE', 1, 'admin', '研发部门', '/nursing/alertRule/32', '172.16.43.100', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-09-12 19:06:18', 4); +INSERT INTO `sys_oper_log` VALUES (340, '报警规则', 3, 'com.zzyl.nursing.controller.AlertRuleController.remove()', 'DELETE', 1, 'admin', '研发部门', '/nursing/alertRule/31', '172.16.43.100', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-09-12 19:06:20', 4); +INSERT INTO `sys_oper_log` VALUES (341, '报警规则', 3, 'com.zzyl.nursing.controller.AlertRuleController.remove()', 'DELETE', 1, 'admin', '研发部门', '/nursing/alertRule/29', '172.16.43.100', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-09-12 19:06:22', 4); +INSERT INTO `sys_oper_log` VALUES (342, '报警规则', 3, 'com.zzyl.nursing.controller.AlertRuleController.remove()', 'DELETE', 1, 'admin', '研发部门', '/nursing/alertRule/30', '172.16.43.100', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-09-12 19:06:24', 4); +INSERT INTO `sys_oper_log` VALUES (343, '报警规则', 3, 'com.zzyl.nursing.controller.AlertRuleController.remove()', 'DELETE', 1, 'admin', '研发部门', '/nursing/alertRule/27', '172.16.43.100', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-09-12 19:06:26', 3); +INSERT INTO `sys_oper_log` VALUES (344, '报警规则', 3, 'com.zzyl.nursing.controller.AlertRuleController.remove()', 'DELETE', 1, 'admin', '研发部门', '/nursing/alertRule/42', '172.16.43.100', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-09-12 19:06:28', 7); +INSERT INTO `sys_oper_log` VALUES (345, '报警规则', 3, 'com.zzyl.nursing.controller.AlertRuleController.remove()', 'DELETE', 1, 'admin', '研发部门', '/nursing/alertRule/43', '172.16.43.100', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-09-12 19:06:30', 3); +INSERT INTO `sys_oper_log` VALUES (346, '报警规则', 3, 'com.zzyl.nursing.controller.AlertRuleController.remove()', 'DELETE', 1, 'admin', '研发部门', '/nursing/alertRule/44', '172.16.43.100', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-09-12 19:06:39', 3); +INSERT INTO `sys_oper_log` VALUES (347, '报警规则', 3, 'com.zzyl.nursing.controller.AlertRuleController.remove()', 'DELETE', 1, 'admin', '研发部门', '/nursing/alertRule/45', '172.16.43.100', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-09-12 19:06:42', 3); +INSERT INTO `sys_oper_log` VALUES (348, '报警规则', 3, 'com.zzyl.nursing.controller.AlertRuleController.remove()', 'DELETE', 1, 'admin', '研发部门', '/nursing/alertRule/47', '172.16.43.100', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-09-12 19:06:44', 3); +INSERT INTO `sys_oper_log` VALUES (349, '报警规则', 3, 'com.zzyl.nursing.controller.AlertRuleController.remove()', 'DELETE', 1, 'admin', '研发部门', '/nursing/alertRule/48', '172.16.43.100', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-09-12 19:06:46', 3); +INSERT INTO `sys_oper_log` VALUES (350, '报警规则', 3, 'com.zzyl.nursing.controller.AlertRuleController.remove()', 'DELETE', 1, 'admin', '研发部门', '/nursing/alertRule/49', '172.16.43.100', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-09-12 19:06:48', 3); +INSERT INTO `sys_oper_log` VALUES (351, '设备', 2, 'com.zzyl.nursing.controller.DeviceController.edit()', 'PUT', 1, 'admin', '研发部门', '/nursing/device', '172.16.43.100', '内网IP', '{\"bindingLocation\":\"1\",\"deviceDescription\":\"1,1,1\",\"deviceName\":\"xzsb001\",\"id\":203,\"iotId\":\"lN27S46N5PArvueMvht1j0rk00\",\"locationType\":1,\"nickname\":\"新增设备001\",\"params\":{},\"physicalLocationType\":2,\"productKey\":\"j0rk0xgSbjY\",\"remark\":\"1楼,101,101-1\",\"updateBy\":\"1\",\"updateTime\":\"2024-09-12 19:15:36\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-09-12 19:15:37', 182); +INSERT INTO `sys_oper_log` VALUES (352, '设备', 2, 'com.zzyl.nursing.controller.DeviceController.edit()', 'PUT', 1, 'admin', '研发部门', '/nursing/device', '172.16.43.100', '内网IP', '{\"bindingLocation\":\"328\",\"deviceName\":\"xzsb001\",\"id\":203,\"iotId\":\"lN27S46N5PArvueMvht1j0rk00\",\"locationType\":0,\"nickname\":\"新增设备001\",\"params\":{},\"physicalLocationType\":-1,\"productKey\":\"j0rk0xgSbjY\",\"remark\":\"老李头儿\",\"updateBy\":\"1\",\"updateTime\":\"2024-09-12 19:16:14\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-09-12 19:16:14', 289); +INSERT INTO `sys_oper_log` VALUES (353, '设备', 2, 'com.zzyl.nursing.controller.DeviceController.edit()', 'PUT', 1, 'admin', '研发部门', '/nursing/device', '172.16.43.100', '内网IP', '{\"bindingLocation\":\"328\",\"deviceName\":\"xzsb001\",\"id\":203,\"iotId\":\"lN27S46N5PArvueMvht1j0rk00\",\"locationType\":0,\"nickname\":\"新增设备002\",\"params\":{},\"physicalLocationType\":-1,\"productKey\":\"j0rk0xgSbjY\",\"remark\":\"老李头儿\",\"updateBy\":\"1\",\"updateTime\":\"2024-09-12 19:16:35\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-09-12 19:16:35', 367); +INSERT INTO `sys_oper_log` VALUES (354, '菜单管理', 3, 'com.zzyl.web.controller.system.SysMenuController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/menu/2034', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-09-12 14:41:12', 17); +INSERT INTO `sys_oper_log` VALUES (355, '菜单管理', 3, 'com.zzyl.web.controller.system.SysMenuController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/menu/2033', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-09-12 14:41:14', 12); +INSERT INTO `sys_oper_log` VALUES (356, '菜单管理', 3, 'com.zzyl.web.controller.system.SysMenuController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/menu/2032', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-09-12 14:41:17', 14); +INSERT INTO `sys_oper_log` VALUES (357, '菜单管理', 3, 'com.zzyl.web.controller.system.SysMenuController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/menu/2031', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-09-12 14:41:20', 12); +INSERT INTO `sys_oper_log` VALUES (358, '菜单管理', 3, 'com.zzyl.web.controller.system.SysMenuController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/menu/2030', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-09-12 14:41:23', 11); +INSERT INTO `sys_oper_log` VALUES (359, '菜单管理', 3, 'com.zzyl.web.controller.system.SysMenuController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/menu/2029', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-09-12 14:41:28', 12); +INSERT INTO `sys_oper_log` VALUES (360, '房型', 1, 'com.zzyl.nursing.controller.RoomTypeController.add()', 'POST', 1, 'admin', '研发部门', '/elder/roomType', '127.0.0.1', '内网IP', '{\"bedCount\":10,\"createBy\":\"1\",\"createTime\":\"2024-09-12 22:52:35\",\"id\":116,\"name\":\"标准双人间\",\"params\":{},\"photo\":\"https://itheim.oss-cn-beijing.aliyuncs.com/91c4a814-efd5-4093-a5ac-963b41047019.png\",\"price\":1500,\"remark\":\"123\",\"status\":0}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-09-12 14:52:35', 34); +INSERT INTO `sys_oper_log` VALUES (361, '房型', 2, 'com.zzyl.nursing.controller.RoomTypeController.edit()', 'PUT', 1, 'admin', '研发部门', '/elder/roomType', '127.0.0.1', '内网IP', '{\"id\":116,\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2024-09-12 22:55:10\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-09-12 14:55:10', 18); +INSERT INTO `sys_oper_log` VALUES (362, '菜单管理', 2, 'com.zzyl.web.controller.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"component\":\"serve/nursingLevel/index\",\"createTime\":\"2024-08-14 08:29:05\",\"icon\":\"guide\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2007,\"menuName\":\"护理等级\",\"menuType\":\"C\",\"orderNum\":1,\"params\":{},\"parentId\":2000,\"path\":\"nursingLevel\",\"perms\":\"serve:level:list\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-03 10:45:44', 50); +INSERT INTO `sys_oper_log` VALUES (363, '菜单管理', 2, 'com.zzyl.web.controller.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"component\":\"serve/level/index\",\"createTime\":\"2024-08-14 08:29:05\",\"icon\":\"guide\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2007,\"menuName\":\"护理等级\",\"menuType\":\"C\",\"orderNum\":1,\"params\":{},\"parentId\":2000,\"path\":\"nursingLevel\",\"perms\":\"serve:level:list\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-03 10:46:33', 20); +INSERT INTO `sys_oper_log` VALUES (364, '菜单管理', 2, 'com.zzyl.web.controller.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"component\":\"\",\"createTime\":\"2024-08-14 08:29:05\",\"icon\":\"#\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2008,\"menuName\":\"护理等级查询\",\"menuType\":\"F\",\"orderNum\":1,\"params\":{},\"parentId\":2007,\"path\":\"#\",\"perms\":\"serve:level:query\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-03 10:47:20', 13); +INSERT INTO `sys_oper_log` VALUES (365, '菜单管理', 2, 'com.zzyl.web.controller.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"component\":\"\",\"createTime\":\"2024-08-14 08:29:05\",\"icon\":\"#\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2009,\"menuName\":\"护理等级新增\",\"menuType\":\"F\",\"orderNum\":2,\"params\":{},\"parentId\":2007,\"path\":\"#\",\"perms\":\"serve:level:add\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-03 10:47:27', 18); +INSERT INTO `sys_oper_log` VALUES (366, '菜单管理', 2, 'com.zzyl.web.controller.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"component\":\"\",\"createTime\":\"2024-08-14 08:29:05\",\"icon\":\"#\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2010,\"menuName\":\"护理等级修改\",\"menuType\":\"F\",\"orderNum\":3,\"params\":{},\"parentId\":2007,\"path\":\"#\",\"perms\":\"serve:level:edit\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-03 10:47:32', 15); +INSERT INTO `sys_oper_log` VALUES (367, '菜单管理', 2, 'com.zzyl.web.controller.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"component\":\"\",\"createTime\":\"2024-08-14 08:29:05\",\"icon\":\"#\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2011,\"menuName\":\"护理等级删除\",\"menuType\":\"F\",\"orderNum\":4,\"params\":{},\"parentId\":2007,\"path\":\"#\",\"perms\":\"serve:level:remove\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-03 10:47:37', 16); +INSERT INTO `sys_oper_log` VALUES (368, '菜单管理', 2, 'com.zzyl.web.controller.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"component\":\"\",\"createTime\":\"2024-08-14 08:29:05\",\"icon\":\"#\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2012,\"menuName\":\"护理等级导出\",\"menuType\":\"F\",\"orderNum\":5,\"params\":{},\"parentId\":2007,\"path\":\"#\",\"perms\":\"serve:level:export\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-03 10:47:42', 13); +INSERT INTO `sys_oper_log` VALUES (369, '菜单管理', 2, 'com.zzyl.web.controller.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"component\":\"serve/plan/index\",\"createTime\":\"2024-08-14 08:29:10\",\"icon\":\"druid\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2013,\"menuName\":\"护理计划\",\"menuType\":\"C\",\"orderNum\":1,\"params\":{},\"parentId\":2000,\"path\":\"plan\",\"perms\":\"serve:plan:list\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-03 10:48:07', 12); +INSERT INTO `sys_oper_log` VALUES (370, '菜单管理', 2, 'com.zzyl.web.controller.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"component\":\"serve/arrange/details\",\"createTime\":\"2024-08-29 06:53:37\",\"icon\":\"#\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2043,\"menuName\":\"任务安排详情\",\"menuType\":\"C\",\"orderNum\":1,\"params\":{},\"parentId\":2000,\"path\":\"arrangeDetails\",\"perms\":\"\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"1\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-03 10:48:50', 15); +INSERT INTO `sys_oper_log` VALUES (371, '菜单管理', 2, 'com.zzyl.web.controller.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"component\":\"serve/oldPeople/index\",\"createTime\":\"2024-08-29 06:52:12\",\"icon\":\"peoples\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2041,\"menuName\":\"负责老人\",\"menuType\":\"C\",\"orderNum\":4,\"params\":{},\"parentId\":2000,\"path\":\"oldPeople\",\"perms\":\"\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-03 10:48:56', 14); +INSERT INTO `sys_oper_log` VALUES (372, '菜单管理', 2, 'com.zzyl.web.controller.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"component\":\"serve/arrange/index\",\"createTime\":\"2024-08-29 06:53:06\",\"icon\":\"redis-list\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2042,\"menuName\":\"任务安排\",\"menuType\":\"C\",\"orderNum\":5,\"params\":{},\"parentId\":2000,\"path\":\"arrange\",\"perms\":\"\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-03 10:49:01', 21); +INSERT INTO `sys_oper_log` VALUES (373, '菜单管理', 2, 'com.zzyl.web.controller.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"component\":\"serve/level/index\",\"createTime\":\"2024-08-14 08:29:05\",\"icon\":\"guide\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2007,\"menuName\":\"护理等级\",\"menuType\":\"C\",\"orderNum\":1,\"params\":{},\"parentId\":2000,\"path\":\"level\",\"perms\":\"serve:level:list\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-03 10:49:43', 14); +INSERT INTO `sys_oper_log` VALUES (374, '菜单管理', 2, 'com.zzyl.web.controller.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"component\":\"serve/plan/index\",\"createTime\":\"2024-08-14 08:29:10\",\"icon\":\"druid\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2013,\"menuName\":\"护理计划\",\"menuType\":\"C\",\"orderNum\":1,\"params\":{},\"parentId\":2000,\"path\":\"plan\",\"perms\":\"serve:plan:list\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-03 10:49:50', 19); +INSERT INTO `sys_oper_log` VALUES (375, '菜单管理', 2, 'com.zzyl.web.controller.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"component\":\"serve/level/index\",\"createTime\":\"2024-08-14 08:29:05\",\"icon\":\"guide\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2007,\"menuName\":\"护理等级\",\"menuType\":\"C\",\"orderNum\":1,\"params\":{},\"parentId\":2000,\"path\":\"level\",\"perms\":\"serve:level:list\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-03 10:49:54', 12); +INSERT INTO `sys_oper_log` VALUES (376, '护理计划', 2, 'com.zzyl.serve.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '研发部门', '/serve/plan', '127.0.0.1', '内网IP', '{\"id\":134,\"planName\":\"2号护理计划\",\"projectPlans\":[{\"createBy\":\"1\",\"createTime\":\"2024-10-03 22:50:56\",\"executeCycle\":0,\"executeFrequency\":1,\"executeTime\":\"19:28:45\",\"id\":1738,\"params\":{},\"planId\":134,\"projectId\":1}],\"sortNo\":1,\"status\":1}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-03 14:50:59', 157); +INSERT INTO `sys_oper_log` VALUES (377, '房间', 1, 'com.zzyl.nursing.controller.RoomController.add()', 'POST', 1, 'admin', '研发部门', '/elder/room', '127.0.0.1', '内网IP', '{\"code\":\"110\",\"createBy\":\"1\",\"createTime\":\"2024-10-03 23:39:54\",\"floorId\":1,\"id\":88,\"params\":{},\"sort\":1,\"typeName\":\"豪华单人间\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-03 15:39:57', 54); +INSERT INTO `sys_oper_log` VALUES (378, '房型', 2, 'com.zzyl.nursing.controller.RoomTypeController.edit()', 'PUT', 1, 'admin', '研发部门', '/elder/roomType', '127.0.0.1', '内网IP', '{\"bedCount\":0,\"createBy\":\"1671403256519078153\",\"createTime\":\"2023-09-26 15:57:50\",\"id\":1,\"introduction\":\"宽敞舒适的套房,配备独立卫生间和基本生活设施,满足独自居住的需求,提供私密性和舒适度\",\"name\":\"单人套房\",\"params\":{},\"photo\":\"https://yjy-slwl-oss.oss-cn-hangzhou.aliyuncs.com/e2f1031b-e23e-4379-95d4-ce8fe382f58f.png\",\"price\":4001,\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2024-10-03 23:54:29\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-03 15:54:32', 40); +INSERT INTO `sys_oper_log` VALUES (379, '房型', 2, 'com.zzyl.nursing.controller.RoomTypeController.edit()', 'PUT', 1, 'admin', '研发部门', '/elder/roomType', '127.0.0.1', '内网IP', '{\"bedCount\":0,\"createBy\":\"1671403256519078153\",\"createTime\":\"2023-09-26 15:57:50\",\"id\":1,\"introduction\":\"宽敞舒适的套房,配备独立卫生间和基本生活设施,满足独自居住的需求,提供私密性和舒适度\",\"name\":\"单人套房\",\"params\":{},\"photo\":\"https://yjy-slwl-oss.oss-cn-hangzhou.aliyuncs.com/e2f1031b-e23e-4379-95d4-ce8fe382f58f.png\",\"price\":4000,\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2024-10-03 23:54:33\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-03 15:54:37', 12); +INSERT INTO `sys_oper_log` VALUES (380, '床位', 1, 'com.zzyl.nursing.controller.BedController.add()', 'POST', 1, 'admin', '研发部门', '/elder/bed', '127.0.0.1', '内网IP', '{\"bedNumber\":\"111\",\"createBy\":\"1\",\"createTime\":\"2024-10-03 23:54:46\",\"id\":2,\"params\":{},\"roomId\":1,\"sort\":1}', NULL, 1, '\r\n### Error updating database. Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'2\' for key \'bed.PRIMARY\'\r\n### The error may exist in com/zzyl/nursing/mapper/BedMapper.java (best guess)\r\n### The error may involve com.zzyl.nursing.mapper.BedMapper.insert-Inline\r\n### The error occurred while setting parameters\r\n### SQL: INSERT INTO bed ( id, bed_number, sort, room_id, create_by, create_time, update_by, update_time ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ? )\r\n### Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'2\' for key \'bed.PRIMARY\'\n; Duplicate entry \'2\' for key \'bed.PRIMARY\'; nested exception is java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'2\' for key \'bed.PRIMARY\'', '2024-10-03 15:54:50', 168); +INSERT INTO `sys_oper_log` VALUES (381, '床位', 1, 'com.zzyl.nursing.controller.BedController.add()', 'POST', 1, 'admin', '研发部门', '/elder/bed', '127.0.0.1', '内网IP', '{\"bedNumber\":\"111\",\"createBy\":\"1\",\"createTime\":\"2024-10-03 23:54:53\",\"id\":2,\"params\":{},\"roomId\":1,\"sort\":1}', NULL, 1, '\r\n### Error updating database. Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'2\' for key \'bed.PRIMARY\'\r\n### The error may exist in com/zzyl/nursing/mapper/BedMapper.java (best guess)\r\n### The error may involve com.zzyl.nursing.mapper.BedMapper.insert-Inline\r\n### The error occurred while setting parameters\r\n### SQL: INSERT INTO bed ( id, bed_number, sort, room_id, create_by, create_time, update_by, update_time ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ? )\r\n### Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'2\' for key \'bed.PRIMARY\'\n; Duplicate entry \'2\' for key \'bed.PRIMARY\'; nested exception is java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'2\' for key \'bed.PRIMARY\'', '2024-10-03 15:54:56', 6); +INSERT INTO `sys_oper_log` VALUES (382, '床位', 1, 'com.zzyl.nursing.controller.BedController.add()', 'POST', 1, 'admin', '研发部门', '/elder/bed', '127.0.0.1', '内网IP', '{\"bedNumber\":\"11111\",\"createBy\":\"1\",\"createTime\":\"2024-10-03 23:55:04\",\"id\":2,\"params\":{},\"roomId\":1,\"sort\":1}', NULL, 1, '\r\n### Error updating database. Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'2\' for key \'bed.PRIMARY\'\r\n### The error may exist in com/zzyl/nursing/mapper/BedMapper.java (best guess)\r\n### The error may involve com.zzyl.nursing.mapper.BedMapper.insert-Inline\r\n### The error occurred while setting parameters\r\n### SQL: INSERT INTO bed ( id, bed_number, sort, room_id, create_by, create_time, update_by, update_time ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ? )\r\n### Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'2\' for key \'bed.PRIMARY\'\n; Duplicate entry \'2\' for key \'bed.PRIMARY\'; nested exception is java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'2\' for key \'bed.PRIMARY\'', '2024-10-03 15:55:07', 5); +INSERT INTO `sys_oper_log` VALUES (383, '床位', 1, 'com.zzyl.nursing.controller.BedController.add()', 'POST', 1, 'admin', '研发部门', '/elder/bed', '127.0.0.1', '内网IP', '{\"bedNumber\":\"11111\",\"createBy\":\"1\",\"createTime\":\"2024-10-03 23:55:07\",\"id\":2,\"params\":{},\"roomId\":1,\"sort\":2}', NULL, 1, '\r\n### Error updating database. Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'2\' for key \'bed.PRIMARY\'\r\n### The error may exist in com/zzyl/nursing/mapper/BedMapper.java (best guess)\r\n### The error may involve com.zzyl.nursing.mapper.BedMapper.insert-Inline\r\n### The error occurred while setting parameters\r\n### SQL: INSERT INTO bed ( id, bed_number, sort, room_id, create_by, create_time, update_by, update_time ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ? )\r\n### Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'2\' for key \'bed.PRIMARY\'\n; Duplicate entry \'2\' for key \'bed.PRIMARY\'; nested exception is java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'2\' for key \'bed.PRIMARY\'', '2024-10-03 15:55:10', 7); +INSERT INTO `sys_oper_log` VALUES (384, '床位', 1, 'com.zzyl.nursing.controller.BedController.add()', 'POST', 1, 'admin', '研发部门', '/elder/bed', '127.0.0.1', '内网IP', '{\"bedNumber\":\"1111\",\"createBy\":\"1\",\"createTime\":\"2024-10-04 00:01:30\",\"params\":{},\"roomId\":1,\"sort\":1}', NULL, 1, '\r\n### Error updating database. Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'1111\' for key \'bed.bed_number\'\r\n### The error may exist in com/zzyl/nursing/mapper/BedMapper.java (best guess)\r\n### The error may involve com.zzyl.nursing.mapper.BedMapper.insert-Inline\r\n### The error occurred while setting parameters\r\n### SQL: INSERT INTO bed ( bed_number, sort, room_id, create_by, create_time, update_by, update_time ) VALUES ( ?, ?, ?, ?, ?, ?, ? )\r\n### Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'1111\' for key \'bed.bed_number\'\n; Duplicate entry \'1111\' for key \'bed.bed_number\'; nested exception is java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'1111\' for key \'bed.bed_number\'', '2024-10-03 16:01:33', 11); +INSERT INTO `sys_oper_log` VALUES (385, '楼层', 1, 'com.zzyl.nursing.controller.FloorController.add()', 'POST', 1, 'admin', '研发部门', '/elder/floor', '127.0.0.1', '内网IP', '{\"code\":1,\"createBy\":\"1\",\"createTime\":\"2024-10-04 00:02:58\",\"id\":413,\"name\":\"13楼\",\"params\":{}}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-03 16:03:01', 15); +INSERT INTO `sys_oper_log` VALUES (386, '床位', 1, 'com.zzyl.nursing.controller.BedController.add()', 'POST', 1, 'admin', '研发部门', '/elder/bed', '127.0.0.1', '内网IP', '{\"bedNumber\":\"1201-1\",\"createBy\":\"1\",\"createTime\":\"2024-10-04 00:03:31\",\"id\":200,\"params\":{},\"roomId\":83,\"sort\":1}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-03 16:03:34', 11); +INSERT INTO `sys_oper_log` VALUES (387, '房间', 3, 'com.zzyl.nursing.controller.RoomController.remove()', 'DELETE', 1, 'admin', '研发部门', '/elder/room/88', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-03 16:12:20', 112); +INSERT INTO `sys_oper_log` VALUES (388, '代码生成', 3, 'com.zzyl.generator.controller.GenController.remove()', 'DELETE', 1, 'admin', '研发部门', '/tool/gen/16', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-06 14:46:26', 96); +INSERT INTO `sys_oper_log` VALUES (389, '代码生成', 3, 'com.zzyl.generator.controller.GenController.remove()', 'DELETE', 1, 'admin', '研发部门', '/tool/gen/17', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-10-06 14:46:28', 50); +INSERT INTO `sys_oper_log` VALUES (390, '菜单管理', 2, 'com.zzyl.web.controller.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"component\":\"nursing/arrange/details\",\"createTime\":\"2024-08-29 06:53:37\",\"icon\":\"#\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2043,\"menuName\":\"任务安排详情\",\"menuType\":\"C\",\"orderNum\":1,\"params\":{},\"parentId\":2000,\"path\":\"arrangeDetails\",\"perms\":\"\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"1\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-11-03 14:24:57', 173); +INSERT INTO `sys_oper_log` VALUES (391, '菜单管理', 2, 'com.zzyl.web.controller.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"component\":\"nursing/oldPeople/index\",\"createTime\":\"2024-08-29 06:52:12\",\"icon\":\"peoples\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2041,\"menuName\":\"负责老人\",\"menuType\":\"C\",\"orderNum\":4,\"params\":{},\"parentId\":2000,\"path\":\"oldPeople\",\"perms\":\"\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-11-03 14:25:05', 20); +INSERT INTO `sys_oper_log` VALUES (392, '菜单管理', 2, 'com.zzyl.web.controller.system.SysMenuController.edit()', 'PUT', 1, 'admin', '研发部门', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"component\":\"nursing/arrange/index\",\"createTime\":\"2024-08-29 06:53:06\",\"icon\":\"redis-list\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2042,\"menuName\":\"任务安排\",\"menuType\":\"C\",\"orderNum\":5,\"params\":{},\"parentId\":2000,\"path\":\"arrange\",\"perms\":\"\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-11-03 14:25:09', 30); +INSERT INTO `sys_oper_log` VALUES (393, '床位', 2, 'com.zzyl.nursing.controller.BedController.edit()', 'PUT', 1, 'admin', '研发部门', '/elder/bed', '127.0.0.1', '内网IP', '{\"bedNumber\":\"108-1\",\"id\":173,\"params\":{},\"sort\":1,\"updateBy\":\"1\",\"updateTime\":\"2024-11-03 23:31:50\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-11-03 15:31:49', 20); +INSERT INTO `sys_oper_log` VALUES (394, '床位', 3, 'com.zzyl.nursing.controller.BedController.remove()', 'DELETE', 1, 'admin', '研发部门', '/elder/bed/188', '127.0.0.1', '内网IP', '[188]', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-11-03 15:32:03', 21); +INSERT INTO `sys_oper_log` VALUES (395, '用户管理', 2, 'com.zzyl.web.controller.system.SysUserController.resetPwd()', 'PUT', 1, 'admin', '研发部门', '/system/user/resetPwd', '127.0.0.1', '内网IP', '{\"admin\":false,\"params\":{},\"updateBy\":\"admin\",\"userId\":101}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-11-03 16:11:29', 162); +INSERT INTO `sys_oper_log` VALUES (396, '用户管理', 2, 'com.zzyl.web.controller.system.SysUserController.resetPwd()', 'PUT', 1, 'admin', '研发部门', '/system/user/resetPwd', '127.0.0.1', '内网IP', '{\"admin\":false,\"params\":{},\"updateBy\":\"admin\",\"userId\":102}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-11-03 16:11:36', 176); +INSERT INTO `sys_oper_log` VALUES (397, '用户管理', 2, 'com.zzyl.web.controller.system.SysUserController.resetPwd()', 'PUT', 1, 'admin', '研发部门', '/system/user/resetPwd', '127.0.0.1', '内网IP', '{\"admin\":false,\"params\":{},\"updateBy\":\"admin\",\"userId\":103}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-11-03 16:11:42', 220); +INSERT INTO `sys_oper_log` VALUES (398, '用户管理', 2, 'com.zzyl.web.controller.system.SysUserController.resetPwd()', 'PUT', 1, 'admin', '研发部门', '/system/user/resetPwd', '127.0.0.1', '内网IP', '{\"admin\":false,\"params\":{},\"updateBy\":\"admin\",\"userId\":104}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-11-03 16:11:47', 171); +INSERT INTO `sys_oper_log` VALUES (399, '用户管理', 2, 'com.zzyl.web.controller.system.SysUserController.resetPwd()', 'PUT', 1, 'admin', '研发部门', '/system/user/resetPwd', '127.0.0.1', '内网IP', '{\"admin\":false,\"params\":{},\"updateBy\":\"admin\",\"userId\":105}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2024-11-03 16:11:57', 217); +INSERT INTO `sys_oper_log` VALUES (400, '床位', 1, 'com.zzyl.nursing.controller.BedController.add()', 'POST', 1, 'admin', '院长办公室', '/elder/bed', '127.0.0.1', '内网IP', '{\"bedNumber\":\"109-2\",\"createBy\":\"1\",\"createTime\":\"2025-01-02 00:37:05\",\"id\":201,\"params\":{},\"roomId\":81,\"sort\":2}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-01-01 16:37:05', 59); +INSERT INTO `sys_oper_log` VALUES (401, '床位', 1, 'com.zzyl.nursing.controller.BedController.add()', 'POST', 1, 'admin', '院长办公室', '/elder/bed', '127.0.0.1', '内网IP', '{\"bedNumber\":\"108-2\",\"createBy\":\"1\",\"createTime\":\"2025-01-02 00:37:31\",\"id\":202,\"params\":{},\"roomId\":67,\"sort\":2}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-01-01 16:37:31', 9); +INSERT INTO `sys_oper_log` VALUES (402, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '院长办公室', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":135,\"params\":{},\"status\":0,\"updateBy\":\"1\",\"updateTime\":\"2025-02-24 09:57:18\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 01:57:18', 28); +INSERT INTO `sys_oper_log` VALUES (403, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '院长办公室', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":135,\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-24 09:57:20\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 01:57:20', 10); +INSERT INTO `sys_oper_log` VALUES (404, '护理项目', 2, 'com.zzyl.nursing.controller.NursingProjectController.edit()', 'PUT', 1, 'admin', '院长办公室', '/nursing/project', '127.0.0.1', '内网IP', '{\"id\":1,\"params\":{},\"status\":0,\"updateBy\":\"1\",\"updateTime\":\"2025-02-24 09:57:28\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 01:57:28', 18); +INSERT INTO `sys_oper_log` VALUES (405, '护理项目', 2, 'com.zzyl.nursing.controller.NursingProjectController.edit()', 'PUT', 1, 'admin', '院长办公室', '/nursing/project', '127.0.0.1', '内网IP', '{\"id\":1,\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-24 09:57:29\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 01:57:29', 11); +INSERT INTO `sys_oper_log` VALUES (406, '代码生成', 6, 'com.zzyl.generator.controller.GenController.importTableSave()', 'POST', 1, 'admin', '院长办公室', '/tool/gen/importTable', '127.0.0.1', '内网IP', '{\"tables\":\"nursing_project_plan\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 02:07:11', 109); +INSERT INTO `sys_oper_log` VALUES (407, '代码生成', 2, 'com.zzyl.generator.controller.GenController.editSave()', 'PUT', 1, 'admin', '院长办公室', '/tool/gen', '127.0.0.1', '内网IP', '{\"businessName\":\"projectPlan\",\"className\":\"NursingProjectPlan\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键ID\",\"columnId\":262,\"columnName\":\"id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2025-02-24 02:07:11\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Integer\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":18,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"PlanId\",\"columnComment\":\"计划id\",\"columnId\":263,\"columnName\":\"plan_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2025-02-24 02:07:11\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"planId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":18,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"ProjectId\",\"columnComment\":\"项目id\",\"columnId\":264,\"columnName\":\"project_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2025-02-24 02:07:11\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"projectId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":18,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"ExecuteTime\",\"columnComment\":\"计划执行时间\",\"columnId\":265,\"columnName\":\"execute_time\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2025-02-24 02:07:11\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"ja', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 02:11:46', 98); +INSERT INTO `sys_oper_log` VALUES (408, '代码生成', 2, 'com.zzyl.generator.controller.GenController.editSave()', 'PUT', 1, 'admin', '院长办公室', '/tool/gen', '127.0.0.1', '内网IP', '{\"businessName\":\"projectPlan\",\"className\":\"NursingProjectPlan\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键ID\",\"columnId\":262,\"columnName\":\"id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2025-02-24 02:07:11\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Integer\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":18,\"updateBy\":\"\",\"updateTime\":\"2025-02-24 02:11:46\",\"usableColumn\":false},{\"capJavaField\":\"PlanId\",\"columnComment\":\"计划id\",\"columnId\":263,\"columnName\":\"plan_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2025-02-24 02:07:11\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"planId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":18,\"updateBy\":\"\",\"updateTime\":\"2025-02-24 02:11:46\",\"usableColumn\":false},{\"capJavaField\":\"ProjectId\",\"columnComment\":\"项目id\",\"columnId\":264,\"columnName\":\"project_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2025-02-24 02:07:11\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"projectId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":18,\"updateBy\":\"\",\"updateTime\":\"2025-02-24 02:11:46\",\"usableColumn\":false},{\"capJavaField\":\"ExecuteTime\",\"columnComment\":\"计划执行时间\",\"columnId\":265,\"columnName\":\"execute_time\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2025-02-24 02:07:11\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 02:13:23', 83); +INSERT INTO `sys_oper_log` VALUES (409, '字典数据', 2, 'com.zzyl.web.controller.system.SysDictDataController.edit()', 'PUT', 1, 'admin', '院长办公室', '/system/dict/data', '127.0.0.1', '内网IP', '{\"createBy\":\"admin\",\"createTime\":\"2024-08-19 11:00:10\",\"default\":false,\"dictCode\":104,\"dictLabel\":\"禁用\",\"dictSort\":0,\"dictType\":\"nursing_plan_status\",\"dictValue\":\"0\",\"isDefault\":\"N\",\"listClass\":\"default\",\"params\":{},\"status\":\"0\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 02:13:37', 15); +INSERT INTO `sys_oper_log` VALUES (410, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '院长办公室', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":135,\"params\":{},\"status\":0,\"updateBy\":\"1\",\"updateTime\":\"2025-02-24 10:13:52\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 02:13:52', 10); +INSERT INTO `sys_oper_log` VALUES (411, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '院长办公室', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":135,\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-24 10:13:56\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 02:13:56', 12); +INSERT INTO `sys_oper_log` VALUES (412, '代码生成', 8, 'com.zzyl.generator.controller.GenController.batchGenCode()', 'GET', 1, 'admin', '院长办公室', '/tool/gen/batchGenCode', '127.0.0.1', '内网IP', '{\"tables\":\"nursing_project_plan\"}', NULL, 0, NULL, '2025-02-24 02:32:40', 341); +INSERT INTO `sys_oper_log` VALUES (413, '护理项目', 2, 'com.zzyl.nursing.controller.NursingProjectController.edit()', 'PUT', 1, 'admin', '院长办公室', '/nursing/project', '127.0.0.1', '内网IP', '{\"id\":4,\"params\":{},\"status\":0,\"updateBy\":\"1\",\"updateTime\":\"2025-02-24 10:46:24\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 02:46:24', 47); +INSERT INTO `sys_oper_log` VALUES (414, '护理项目', 2, 'com.zzyl.nursing.controller.NursingProjectController.edit()', 'PUT', 1, 'admin', '院长办公室', '/nursing/project', '127.0.0.1', '内网IP', '{\"id\":1,\"params\":{},\"status\":0,\"updateBy\":\"1\",\"updateTime\":\"2025-02-24 10:46:27\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 02:46:27', 18); +INSERT INTO `sys_oper_log` VALUES (415, '护理计划', 1, 'com.zzyl.nursing.controller.NursingPlanController.add()', 'POST', 1, 'admin', '院长办公室', '/nursing/plan', '127.0.0.1', '内网IP', '{\"planName\":\"4号护理计划\",\"projectPlans\":[{\"createBy\":\"1\",\"createTime\":\"2025-02-24 11:42:54\",\"executeCycle\":0,\"executeFrequency\":1,\"executeTime\":\"07:30:11\",\"id\":1743,\"params\":{},\"planId\":136,\"projectId\":7},{\"createBy\":\"1\",\"createTime\":\"2025-02-24 11:42:54\",\"executeCycle\":2,\"executeFrequency\":2,\"executeTime\":\"15:42:39\",\"id\":1744,\"params\":{},\"planId\":136,\"projectId\":9}],\"sortNo\":4,\"status\":1}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 03:42:54', 82); +INSERT INTO `sys_oper_log` VALUES (416, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '院长办公室', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":135,\"params\":{},\"status\":0,\"updateBy\":\"1\",\"updateTime\":\"2025-02-24 12:03:10\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 04:03:10', 77); +INSERT INTO `sys_oper_log` VALUES (417, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '院长办公室', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":136,\"planName\":\"4号护理计划\",\"projectPlans\":[{\"createBy\":\"1\",\"createTime\":\"2025-02-24 11:42:54\",\"executeCycle\":2,\"executeFrequency\":3,\"executeTime\":\"15:42:39\",\"id\":1744,\"params\":{},\"planId\":136,\"projectId\":9},{\"createBy\":\"1\",\"createTime\":\"2025-02-24 13:03:08\",\"executeCycle\":1,\"executeFrequency\":2,\"executeTime\":\"19:02:48\",\"id\":1745,\"params\":{},\"planId\":136,\"projectId\":5}],\"sortNo\":4,\"status\":1}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 05:03:07', 136); +INSERT INTO `sys_oper_log` VALUES (418, '护理计划', 1, 'com.zzyl.nursing.controller.NursingPlanController.add()', 'POST', 1, 'admin', '院长办公室', '/nursing/plan', '127.0.0.1', '内网IP', '{\"planName\":\"5号护理计划\",\"projectPlans\":[{\"createBy\":\"1\",\"createTime\":\"2025-02-24 13:08:29\",\"executeCycle\":1,\"executeFrequency\":1,\"executeTime\":\"13:03:08\",\"id\":1746,\"params\":{},\"planId\":137,\"projectId\":5},{\"createBy\":\"1\",\"createTime\":\"2025-02-24 13:08:29\",\"executeCycle\":0,\"executeFrequency\":1,\"executeTime\":\"13:08:23\",\"id\":1747,\"params\":{},\"planId\":137,\"projectId\":3}],\"sortNo\":1,\"status\":0}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 05:08:28', 166); +INSERT INTO `sys_oper_log` VALUES (419, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '院长办公室', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":137,\"status\":1}', NULL, 1, '', '2025-02-24 05:08:45', 106); +INSERT INTO `sys_oper_log` VALUES (420, '护理计划', 3, 'com.zzyl.nursing.controller.NursingPlanController.remove()', 'DELETE', 1, 'admin', '院长办公室', '/nursing/plan/137', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作失败\",\"code\":500}', 0, NULL, '2025-02-24 05:08:52', 28); +INSERT INTO `sys_oper_log` VALUES (421, '护理计划', 3, 'com.zzyl.nursing.controller.NursingPlanController.remove()', 'DELETE', 1, 'admin', '院长办公室', '/nursing/plan/137', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作失败\",\"code\":500}', 0, NULL, '2025-02-24 05:09:03', 27); +INSERT INTO `sys_oper_log` VALUES (422, '护理计划', 1, 'com.zzyl.nursing.controller.NursingPlanController.add()', 'POST', 1, 'admin', '院长办公室', '/nursing/plan', '127.0.0.1', '内网IP', '{\"planName\":\"5号护理计划\",\"projectPlans\":[{\"createBy\":\"1\",\"createTime\":\"2025-02-24 13:09:45\",\"executeCycle\":0,\"executeFrequency\":1,\"executeTime\":\"13:09:30\",\"id\":1748,\"params\":{},\"planId\":138,\"projectId\":3},{\"createBy\":\"1\",\"createTime\":\"2025-02-24 13:09:45\",\"executeCycle\":2,\"executeFrequency\":1,\"executeTime\":\"13:09:40\",\"id\":1749,\"params\":{},\"planId\":138,\"projectId\":9}],\"sortNo\":1,\"status\":1}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 05:09:44', 20); +INSERT INTO `sys_oper_log` VALUES (423, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '院长办公室', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":138,\"status\":0}', NULL, 1, '', '2025-02-24 05:10:01', 23); +INSERT INTO `sys_oper_log` VALUES (424, '护理计划', 3, 'com.zzyl.nursing.controller.NursingPlanController.remove()', 'DELETE', 1, 'admin', '院长办公室', '/nursing/plan/138', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 05:10:04', 19); +INSERT INTO `sys_oper_log` VALUES (425, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '院长办公室', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":136,\"status\":0}', NULL, 1, '', '2025-02-24 05:13:15', 29); +INSERT INTO `sys_oper_log` VALUES (426, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '院长办公室', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":136,\"status\":0}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 05:14:48', 198); +INSERT INTO `sys_oper_log` VALUES (427, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '院长办公室', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":136,\"status\":1}', NULL, 1, '删除原有项目失败', '2025-02-24 05:14:53', 25); +INSERT INTO `sys_oper_log` VALUES (428, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '院长办公室', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":136,\"status\":1}', NULL, 1, '删除原有项目失败', '2025-02-24 05:14:56', 24); +INSERT INTO `sys_oper_log` VALUES (429, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '院长办公室', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":136,\"status\":1}', NULL, 1, '删除原有项目失败', '2025-02-24 05:15:13', 39); +INSERT INTO `sys_oper_log` VALUES (430, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '院长办公室', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":136,\"status\":1}', NULL, 1, '删除原有项目失败', '2025-02-24 05:22:36', 12127); +INSERT INTO `sys_oper_log` VALUES (431, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '院长办公室', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":136,\"status\":1}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 05:26:46', 131); +INSERT INTO `sys_oper_log` VALUES (432, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '院长办公室', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":135,\"status\":1}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 05:26:57', 28); +INSERT INTO `sys_oper_log` VALUES (433, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '院长办公室', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":135,\"status\":0}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 05:26:59', 31); +INSERT INTO `sys_oper_log` VALUES (434, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '院长办公室', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":136,\"planName\":\"4号护理计划\",\"projectPlans\":[],\"sortNo\":4,\"status\":0}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 05:27:09', 33); +INSERT INTO `sys_oper_log` VALUES (435, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '院长办公室', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":136,\"status\":1}', NULL, 1, '删除原有项目失败', '2025-02-24 05:28:06', 167); +INSERT INTO `sys_oper_log` VALUES (436, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '院长办公室', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":136,\"status\":1}', NULL, 1, '删除原有项目失败', '2025-02-24 05:29:00', 31); +INSERT INTO `sys_oper_log` VALUES (437, '护理计划', 3, 'com.zzyl.nursing.controller.NursingPlanController.remove()', 'DELETE', 1, 'admin', '院长办公室', '/nursing/plan/136', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 05:29:09', 30); +INSERT INTO `sys_oper_log` VALUES (438, '护理计划', 1, 'com.zzyl.nursing.controller.NursingPlanController.add()', 'POST', 1, 'admin', '院长办公室', '/nursing/plan', '127.0.0.1', '内网IP', '{\"planName\":\"4号护理计划\",\"projectPlans\":[{\"createBy\":\"1\",\"createTime\":\"2025-02-24 13:29:44\",\"executeCycle\":1,\"executeFrequency\":4,\"executeTime\":\"09:29:09\",\"id\":1750,\"params\":{},\"planId\":139,\"projectId\":2},{\"createBy\":\"1\",\"createTime\":\"2025-02-24 13:29:44\",\"executeCycle\":0,\"executeFrequency\":1,\"executeTime\":\"08:29:34\",\"id\":1751,\"params\":{},\"planId\":139,\"projectId\":3}],\"sortNo\":1,\"status\":1}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 05:29:43', 62); +INSERT INTO `sys_oper_log` VALUES (439, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '院长办公室', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":139,\"planName\":\"4号护理计划\",\"projectPlans\":[{\"createBy\":\"1\",\"createTime\":\"2025-02-24 13:29:44\",\"executeCycle\":1,\"executeFrequency\":4,\"executeTime\":\"09:29:09\",\"id\":1750,\"params\":{},\"planId\":139,\"projectId\":2},{\"createBy\":\"1\",\"createTime\":\"2025-02-24 13:29:44\",\"executeCycle\":0,\"executeFrequency\":1,\"executeTime\":\"08:29:34\",\"id\":1751,\"params\":{},\"planId\":139,\"projectId\":3}],\"sortNo\":1,\"status\":0}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 05:29:53', 36); +INSERT INTO `sys_oper_log` VALUES (440, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '院长办公室', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":139,\"status\":1}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 05:29:59', 22); +INSERT INTO `sys_oper_log` VALUES (441, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '院长办公室', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":139,\"status\":0}', NULL, 1, '删除原有项目失败', '2025-02-24 05:30:01', 27); +INSERT INTO `sys_oper_log` VALUES (442, '护理计划', 3, 'com.zzyl.nursing.controller.NursingPlanController.remove()', 'DELETE', 1, 'admin', '院长办公室', '/nursing/plan/139', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 05:30:10', 20); +INSERT INTO `sys_oper_log` VALUES (443, '护理计划', 1, 'com.zzyl.nursing.controller.NursingPlanController.add()', 'POST', 1, 'admin', '院长办公室', '/nursing/plan', '127.0.0.1', '内网IP', '{\"planName\":\"4号\",\"projectPlans\":[{\"createBy\":\"1\",\"createTime\":\"2025-02-24 13:50:02\",\"executeCycle\":0,\"executeFrequency\":1,\"executeTime\":\"13:50:46\",\"id\":1752,\"params\":{},\"planId\":140,\"projectId\":7},{\"createBy\":\"1\",\"createTime\":\"2025-02-24 13:50:02\",\"executeCycle\":1,\"executeFrequency\":1,\"executeTime\":\"13:49:57\",\"id\":1753,\"params\":{},\"planId\":140,\"projectId\":5}],\"sortNo\":1,\"status\":1}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 05:50:01', 86); +INSERT INTO `sys_oper_log` VALUES (444, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '院长办公室', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":140,\"status\":0}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 05:50:07', 62); +INSERT INTO `sys_oper_log` VALUES (445, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '院长办公室', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":140,\"status\":1}', NULL, 1, '删除原有项目失败', '2025-02-24 05:50:12', 22); +INSERT INTO `sys_oper_log` VALUES (446, '护理计划', 3, 'com.zzyl.nursing.controller.NursingPlanController.remove()', 'DELETE', 1, 'admin', '院长办公室', '/nursing/plan/140', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 05:50:33', 18); +INSERT INTO `sys_oper_log` VALUES (447, '护理计划', 1, 'com.zzyl.nursing.controller.NursingPlanController.add()', 'POST', 1, 'admin', '院长办公室', '/nursing/plan', '127.0.0.1', '内网IP', '{\"planName\":\"4号\",\"projectPlans\":[{\"createBy\":\"1\",\"createTime\":\"2025-02-24 13:50:51\",\"executeCycle\":1,\"executeFrequency\":2,\"executeTime\":\"13:50:33\",\"id\":1754,\"params\":{},\"planId\":141,\"projectId\":5},{\"createBy\":\"1\",\"createTime\":\"2025-02-24 13:50:51\",\"executeCycle\":0,\"executeFrequency\":1,\"executeTime\":\"13:50:46\",\"id\":1755,\"params\":{},\"planId\":141,\"projectId\":8}],\"sortNo\":1,\"status\":1}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 05:50:50', 22); +INSERT INTO `sys_oper_log` VALUES (448, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.editStatus()', 'PUT', 1, 'admin', '院长办公室', '/nursing/plan/status', '127.0.0.1', '内网IP', '{\"id\":141,\"status\":0}', NULL, 1, 'nested exception is org.apache.ibatis.exceptions.PersistenceException: \r\n### Error updating database. Cause: com.baomidou.mybatisplus.core.exceptions.MybatisPlusException: Failed to process, Error SQL: UPDATE nursing_plan \n \n WHERE (id = ?)\r\n### The error may exist in com/zzyl/nursing/mapper/NursingPlanMapper.java (best guess)\r\n### The error may involve com.zzyl.nursing.mapper.NursingPlanMapper.update\r\n### The error occurred while executing an update\r\n### Cause: com.baomidou.mybatisplus.core.exceptions.MybatisPlusException: Failed to process, Error SQL: UPDATE nursing_plan \n \n WHERE (id = ?)', '2025-02-24 05:50:54', 12); +INSERT INTO `sys_oper_log` VALUES (449, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.editStatus()', 'PUT', 1, 'admin', '院长办公室', '/nursing/plan/status', '127.0.0.1', '内网IP', '{\"id\":141,\"status\":0}', NULL, 1, 'nested exception is org.apache.ibatis.exceptions.PersistenceException: \r\n### Error updating database. Cause: com.baomidou.mybatisplus.core.exceptions.MybatisPlusException: Failed to process, Error SQL: UPDATE nursing_plan \n \n WHERE (id = ?)\r\n### The error may exist in com/zzyl/nursing/mapper/NursingPlanMapper.java (best guess)\r\n### The error may involve com.zzyl.nursing.mapper.NursingPlanMapper.update\r\n### The error occurred while executing an update\r\n### Cause: com.baomidou.mybatisplus.core.exceptions.MybatisPlusException: Failed to process, Error SQL: UPDATE nursing_plan \n \n WHERE (id = ?)', '2025-02-24 05:50:57', 6); +INSERT INTO `sys_oper_log` VALUES (450, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.editStatus()', 'PUT', 1, 'admin', '院长办公室', '/nursing/plan/status', '127.0.0.1', '内网IP', '{\"id\":141,\"status\":0}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 05:53:54', 81); +INSERT INTO `sys_oper_log` VALUES (451, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.editStatus()', 'PUT', 1, 'admin', '院长办公室', '/nursing/plan/status', '127.0.0.1', '内网IP', '{\"id\":141,\"status\":1}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 05:53:57', 18); +INSERT INTO `sys_oper_log` VALUES (452, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.editStatus()', 'PUT', 1, 'admin', '院长办公室', '/nursing/plan/status', '127.0.0.1', '内网IP', '{\"id\":141,\"status\":0}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 05:54:25', 13); +INSERT INTO `sys_oper_log` VALUES (453, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.editStatus()', 'PUT', 1, 'admin', '院长办公室', '/nursing/plan/status', '127.0.0.1', '内网IP', '{\"id\":141,\"status\":1}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 05:54:31', 13); +INSERT INTO `sys_oper_log` VALUES (454, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.editStatus()', 'PUT', 1, 'admin', '院长办公室', '/nursing/plan/status', '127.0.0.1', '内网IP', '{\"id\":141,\"status\":0}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 07:25:44', 149); +INSERT INTO `sys_oper_log` VALUES (455, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.editStatus()', 'PUT', 1, 'admin', '院长办公室', '/nursing/plan/status', '127.0.0.1', '内网IP', '{\"id\":141,\"status\":1}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 07:26:01', 21); +INSERT INTO `sys_oper_log` VALUES (456, '护理项目', 2, 'com.zzyl.nursing.controller.NursingProjectController.edit()', 'PUT', 1, 'admin', '院长办公室', '/nursing/project', '127.0.0.1', '内网IP', '{\"id\":8,\"params\":{},\"status\":0,\"updateBy\":\"1\",\"updateTime\":\"2025-02-24 15:26:16\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 07:26:15', 30); +INSERT INTO `sys_oper_log` VALUES (457, '房型', 1, 'com.zzyl.nursing.controller.RoomTypeController.add()', 'POST', 1, 'admin', '院长办公室', '/elder/roomType', '127.0.0.1', '内网IP', '{\"bedCount\":3,\"createBy\":\"1\",\"createTime\":\"2025-02-24 15:43:09\",\"id\":117,\"name\":\"豪华三人间\",\"params\":{},\"photo\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/24/c63b185301aa44fb81a00fc8818fa010.png\",\"price\":1000,\"status\":0}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 07:43:08', 51); +INSERT INTO `sys_oper_log` VALUES (458, '房型', 2, 'com.zzyl.nursing.controller.RoomTypeController.edit()', 'PUT', 1, 'admin', '院长办公室', '/elder/roomType', '127.0.0.1', '内网IP', '{\"bedCount\":3,\"createBy\":\"1\",\"createTime\":\"2025-02-24 15:43:09\",\"id\":117,\"introduction\":\"豪华三人间\",\"name\":\"豪华三人间\",\"params\":{},\"photo\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/24/c63b185301aa44fb81a00fc8818fa010.png\",\"price\":1000,\"status\":0,\"updateBy\":\"1\",\"updateTime\":\"2025-02-24 15:57:46\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 07:57:46', 35); +INSERT INTO `sys_oper_log` VALUES (459, '房型', 2, 'com.zzyl.nursing.controller.RoomTypeController.edit()', 'PUT', 1, 'admin', '院长办公室', '/elder/roomType', '127.0.0.1', '内网IP', '{\"id\":117,\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-24 15:57:50\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 07:57:49', 22); +INSERT INTO `sys_oper_log` VALUES (460, '房间', 1, 'com.zzyl.nursing.controller.RoomController.add()', 'POST', 1, 'admin', '院长办公室', '/elder/room', '127.0.0.1', '内网IP', '{\"code\":\"110\",\"createBy\":\"1\",\"createTime\":\"2025-02-24 15:58:09\",\"floorId\":1,\"id\":5,\"params\":{},\"sort\":1,\"typeName\":\"双人套房\"}', NULL, 1, '\r\n### Error updating database. Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'5\' for key \'room.PRIMARY\'\r\n### The error may exist in com/zzyl/nursing/mapper/RoomMapper.java (best guess)\r\n### The error may involve com.zzyl.nursing.mapper.RoomMapper.insert-Inline\r\n### The error occurred while setting parameters\r\n### SQL: INSERT INTO room ( id, code, sort, type_name, floor_id, create_by, create_time ) VALUES ( ?, ?, ?, ?, ?, ?, ? )\r\n### Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'5\' for key \'room.PRIMARY\'\n; Duplicate entry \'5\' for key \'room.PRIMARY\'; nested exception is java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'5\' for key \'room.PRIMARY\'', '2025-02-24 07:58:08', 74); +INSERT INTO `sys_oper_log` VALUES (461, '房间', 1, 'com.zzyl.nursing.controller.RoomController.add()', 'POST', 1, 'admin', '院长办公室', '/elder/room', '127.0.0.1', '内网IP', '{\"code\":\"110\",\"createBy\":\"1\",\"createTime\":\"2025-02-24 15:59:21\",\"floorId\":1,\"id\":5,\"params\":{},\"sort\":1,\"typeName\":\"双人套房\"}', NULL, 1, '\r\n### Error updating database. Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'5\' for key \'room.PRIMARY\'\r\n### The error may exist in com/zzyl/nursing/mapper/RoomMapper.java (best guess)\r\n### The error may involve com.zzyl.nursing.mapper.RoomMapper.insert-Inline\r\n### The error occurred while setting parameters\r\n### SQL: INSERT INTO room ( id, code, sort, type_name, floor_id, create_by, create_time ) VALUES ( ?, ?, ?, ?, ?, ?, ? )\r\n### Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'5\' for key \'room.PRIMARY\'\n; Duplicate entry \'5\' for key \'room.PRIMARY\'; nested exception is java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'5\' for key \'room.PRIMARY\'', '2025-02-24 07:59:20', 7); +INSERT INTO `sys_oper_log` VALUES (462, '房间', 1, 'com.zzyl.nursing.controller.RoomController.add()', 'POST', 1, 'admin', '院长办公室', '/elder/room', '127.0.0.1', '内网IP', '{\"code\":\"110\",\"createBy\":\"1\",\"createTime\":\"2025-02-24 15:59:38\",\"floorId\":1,\"id\":5,\"params\":{},\"sort\":1,\"typeName\":\"标准双人间\"}', NULL, 1, '\r\n### Error updating database. Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'5\' for key \'room.PRIMARY\'\r\n### The error may exist in com/zzyl/nursing/mapper/RoomMapper.java (best guess)\r\n### The error may involve com.zzyl.nursing.mapper.RoomMapper.insert-Inline\r\n### The error occurred while setting parameters\r\n### SQL: INSERT INTO room ( id, code, sort, type_name, floor_id, create_by, create_time ) VALUES ( ?, ?, ?, ?, ?, ?, ? )\r\n### Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'5\' for key \'room.PRIMARY\'\n; Duplicate entry \'5\' for key \'room.PRIMARY\'; nested exception is java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'5\' for key \'room.PRIMARY\'', '2025-02-24 07:59:37', 5); +INSERT INTO `sys_oper_log` VALUES (463, '房间', 1, 'com.zzyl.nursing.controller.RoomController.add()', 'POST', 1, 'admin', '院长办公室', '/elder/room', '127.0.0.1', '内网IP', '{\"code\":\"110\",\"createBy\":\"1\",\"createTime\":\"2025-02-24 16:02:12\",\"floorId\":1,\"id\":5,\"params\":{},\"sort\":1,\"typeName\":\"标准双人间\"}', NULL, 1, '\r\n### Error updating database. Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'5\' for key \'room.PRIMARY\'\r\n### The error may exist in com/zzyl/nursing/mapper/RoomMapper.java (best guess)\r\n### The error may involve com.zzyl.nursing.mapper.RoomMapper.insert-Inline\r\n### The error occurred while setting parameters\r\n### SQL: INSERT INTO room ( id, code, sort, type_name, floor_id, create_by, create_time ) VALUES ( ?, ?, ?, ?, ?, ?, ? )\r\n### Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'5\' for key \'room.PRIMARY\'\n; Duplicate entry \'5\' for key \'room.PRIMARY\'; nested exception is java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'5\' for key \'room.PRIMARY\'', '2025-02-24 08:02:11', 90); +INSERT INTO `sys_oper_log` VALUES (464, '房间', 1, 'com.zzyl.nursing.controller.RoomController.add()', 'POST', 1, 'admin', '院长办公室', '/elder/room', '127.0.0.1', '内网IP', '{\"code\":\"110\",\"createBy\":\"1\",\"createTime\":\"2025-02-24 16:04:39\",\"floorId\":1,\"id\":5,\"params\":{},\"sort\":1,\"typeName\":\"标准双人间\"}', NULL, 1, '\r\n### Error updating database. Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'5\' for key \'room.PRIMARY\'\r\n### The error may exist in com/zzyl/nursing/mapper/RoomMapper.java (best guess)\r\n### The error may involve com.zzyl.nursing.mapper.RoomMapper.insert-Inline\r\n### The error occurred while setting parameters\r\n### SQL: INSERT INTO room ( id, code, sort, type_name, floor_id, create_by, create_time ) VALUES ( ?, ?, ?, ?, ?, ?, ? )\r\n### Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'5\' for key \'room.PRIMARY\'\n; Duplicate entry \'5\' for key \'room.PRIMARY\'; nested exception is java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'5\' for key \'room.PRIMARY\'', '2025-02-24 08:04:38', 11); +INSERT INTO `sys_oper_log` VALUES (465, '房型', 1, 'com.zzyl.nursing.controller.RoomTypeController.add()', 'POST', 1, 'admin', '院长办公室', '/elder/roomType', '127.0.0.1', '内网IP', '{\"bedCount\":1,\"createBy\":\"1\",\"createTime\":\"2025-02-24 16:06:26\",\"id\":118,\"introduction\":\"特护房型\",\"name\":\"特护房型\",\"params\":{},\"photo\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/24/a117e4c5c7484176a50bb6cf7daa48fa.png\",\"price\":2000,\"status\":0}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 08:06:25', 18); +INSERT INTO `sys_oper_log` VALUES (466, '房型', 2, 'com.zzyl.nursing.controller.RoomTypeController.edit()', 'PUT', 1, 'admin', '院长办公室', '/elder/roomType', '127.0.0.1', '内网IP', '{\"id\":118,\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-24 16:06:32\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 08:06:31', 43); +INSERT INTO `sys_oper_log` VALUES (467, '房型', 2, 'com.zzyl.nursing.controller.RoomTypeController.edit()', 'PUT', 1, 'admin', '院长办公室', '/elder/roomType', '127.0.0.1', '内网IP', '{\"id\":103,\"params\":{},\"status\":0,\"updateBy\":\"1\",\"updateTime\":\"2025-02-24 16:06:36\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 08:06:35', 12); +INSERT INTO `sys_oper_log` VALUES (468, '房间', 1, 'com.zzyl.nursing.controller.RoomController.add()', 'POST', 1, 'admin', '院长办公室', '/elder/room', '127.0.0.1', '内网IP', '{\"code\":\"110\",\"createBy\":\"1\",\"createTime\":\"2025-02-24 16:30:02\",\"floorId\":1,\"id\":89,\"params\":{},\"sort\":1,\"typeName\":\"双人套房\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 08:30:01', 19); +INSERT INTO `sys_oper_log` VALUES (469, '床位', 1, 'com.zzyl.nursing.controller.BedController.add()', 'POST', 1, 'admin', '院长办公室', '/elder/bed', '127.0.0.1', '内网IP', '{\"bedNumber\":\"110-1\",\"createBy\":\"1\",\"createTime\":\"2025-02-24 16:30:21\",\"id\":203,\"params\":{},\"roomId\":89,\"sort\":1}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 08:30:20', 27); +INSERT INTO `sys_oper_log` VALUES (470, '床位', 3, 'com.zzyl.nursing.controller.BedController.remove()', 'DELETE', 1, 'admin', '院长办公室', '/elder/bed/203', '127.0.0.1', '内网IP', '[203]', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 08:30:40', 30); +INSERT INTO `sys_oper_log` VALUES (471, '床位', 1, 'com.zzyl.nursing.controller.BedController.add()', 'POST', 1, 'admin', '院长办公室', '/elder/bed', '127.0.0.1', '内网IP', '{\"bedNumber\":\"110-1\",\"createBy\":\"1\",\"createTime\":\"2025-02-24 16:31:05\",\"id\":204,\"params\":{},\"roomId\":89,\"sort\":1}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 08:31:04', 8); +INSERT INTO `sys_oper_log` VALUES (472, '床位', 1, 'com.zzyl.nursing.controller.BedController.add()', 'POST', 1, 'admin', '院长办公室', '/elder/bed', '127.0.0.1', '内网IP', '{\"bedNumber\":\"110-2\",\"createBy\":\"1\",\"createTime\":\"2025-02-24 16:31:10\",\"id\":205,\"params\":{},\"roomId\":89,\"sort\":1}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 08:31:09', 15); +INSERT INTO `sys_oper_log` VALUES (473, '床位', 1, 'com.zzyl.nursing.controller.BedController.add()', 'POST', 1, 'admin', '院长办公室', '/elder/bed', '127.0.0.1', '内网IP', '{\"bedNumber\":\"110-3\",\"createBy\":\"1\",\"createTime\":\"2025-02-24 16:38:18\",\"id\":205,\"params\":{},\"roomId\":89,\"sort\":1}', NULL, 1, '\r\n### Error updating database. Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'205\' for key \'bed.PRIMARY\'\r\n### The error may exist in com/zzyl/nursing/mapper/BedMapper.java (best guess)\r\n### The error may involve com.zzyl.nursing.mapper.BedMapper.insert-Inline\r\n### The error occurred while setting parameters\r\n### SQL: INSERT INTO bed ( id, bed_number, sort, room_id, create_by, create_time ) VALUES ( ?, ?, ?, ?, ?, ? )\r\n### Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'205\' for key \'bed.PRIMARY\'\n; Duplicate entry \'205\' for key \'bed.PRIMARY\'; nested exception is java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'205\' for key \'bed.PRIMARY\'', '2025-02-24 08:38:17', 9); +INSERT INTO `sys_oper_log` VALUES (474, '床位', 1, 'com.zzyl.nursing.controller.BedController.add()', 'POST', 1, 'admin', '院长办公室', '/elder/bed', '127.0.0.1', '内网IP', '{\"bedNumber\":\"109-3\",\"createBy\":\"1\",\"createTime\":\"2025-02-24 16:38:29\",\"id\":205,\"params\":{},\"roomId\":81,\"sort\":1}', NULL, 1, '\r\n### Error updating database. Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'205\' for key \'bed.PRIMARY\'\r\n### The error may exist in com/zzyl/nursing/mapper/BedMapper.java (best guess)\r\n### The error may involve com.zzyl.nursing.mapper.BedMapper.insert-Inline\r\n### The error occurred while setting parameters\r\n### SQL: INSERT INTO bed ( id, bed_number, sort, room_id, create_by, create_time ) VALUES ( ?, ?, ?, ?, ?, ? )\r\n### Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'205\' for key \'bed.PRIMARY\'\n; Duplicate entry \'205\' for key \'bed.PRIMARY\'; nested exception is java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'205\' for key \'bed.PRIMARY\'', '2025-02-24 08:38:28', 13); +INSERT INTO `sys_oper_log` VALUES (475, '床位', 1, 'com.zzyl.nursing.controller.BedController.add()', 'POST', 1, 'admin', '院长办公室', '/elder/bed', '127.0.0.1', '内网IP', '{\"bedNumber\":\"110-3\",\"createBy\":\"1\",\"createTime\":\"2025-02-24 16:38:55\",\"id\":205,\"params\":{},\"roomId\":89,\"sort\":1}', NULL, 1, '\r\n### Error updating database. Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'205\' for key \'bed.PRIMARY\'\r\n### The error may exist in com/zzyl/nursing/mapper/BedMapper.java (best guess)\r\n### The error may involve com.zzyl.nursing.mapper.BedMapper.insert-Inline\r\n### The error occurred while setting parameters\r\n### SQL: INSERT INTO bed ( id, bed_number, sort, room_id, create_by, create_time ) VALUES ( ?, ?, ?, ?, ?, ? )\r\n### Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'205\' for key \'bed.PRIMARY\'\n; Duplicate entry \'205\' for key \'bed.PRIMARY\'; nested exception is java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'205\' for key \'bed.PRIMARY\'', '2025-02-24 08:38:54', 5); +INSERT INTO `sys_oper_log` VALUES (476, '房间', 1, 'com.zzyl.nursing.controller.RoomController.add()', 'POST', 1, 'admin', '院长办公室', '/elder/room', '127.0.0.1', '内网IP', '{\"code\":\"111\",\"createBy\":\"1\",\"createTime\":\"2025-02-24 16:39:03\",\"floorId\":1,\"id\":81,\"params\":{},\"sort\":1,\"typeName\":\"单人套房\"}', NULL, 1, '\r\n### Error updating database. Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'81\' for key \'room.PRIMARY\'\r\n### The error may exist in com/zzyl/nursing/mapper/RoomMapper.java (best guess)\r\n### The error may involve com.zzyl.nursing.mapper.RoomMapper.insert-Inline\r\n### The error occurred while setting parameters\r\n### SQL: INSERT INTO room ( id, code, sort, type_name, floor_id, create_by, create_time ) VALUES ( ?, ?, ?, ?, ?, ?, ? )\r\n### Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'81\' for key \'room.PRIMARY\'\n; Duplicate entry \'81\' for key \'room.PRIMARY\'; nested exception is java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'81\' for key \'room.PRIMARY\'', '2025-02-24 08:39:02', 8); +INSERT INTO `sys_oper_log` VALUES (477, '房间', 1, 'com.zzyl.nursing.controller.RoomController.add()', 'POST', 1, 'admin', '院长办公室', '/elder/room', '127.0.0.1', '内网IP', '{\"code\":\"111\",\"createBy\":\"1\",\"createTime\":\"2025-02-24 16:39:12\",\"floorId\":1,\"id\":90,\"params\":{},\"sort\":1,\"typeName\":\"单人套房\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 08:39:11', 11); +INSERT INTO `sys_oper_log` VALUES (478, '床位', 1, 'com.zzyl.nursing.controller.BedController.add()', 'POST', 1, 'admin', '院长办公室', '/elder/bed', '127.0.0.1', '内网IP', '{\"bedNumber\":\"110-3\",\"createBy\":\"1\",\"createTime\":\"2025-02-24 16:39:21\",\"id\":206,\"params\":{},\"roomId\":89,\"sort\":1}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 08:39:20', 10); +INSERT INTO `sys_oper_log` VALUES (479, '床位', 3, 'com.zzyl.nursing.controller.BedController.remove()', 'DELETE', 1, 'admin', '院长办公室', '/elder/bed/206', '127.0.0.1', '内网IP', '[206]', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 08:39:26', 10); +INSERT INTO `sys_oper_log` VALUES (480, '房间', 3, 'com.zzyl.nursing.controller.RoomController.remove()', 'DELETE', 1, 'admin', '院长办公室', '/elder/room/90', '127.0.0.1', '内网IP', '[90]', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 08:39:29', 14); +INSERT INTO `sys_oper_log` VALUES (481, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.editStatus()', 'PUT', 1, 'admin', '院长办公室', '/nursing/plan/status', '127.0.0.1', '内网IP', '{\"id\":141,\"status\":0}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 10:16:13', 47); +INSERT INTO `sys_oper_log` VALUES (482, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.editStatus()', 'PUT', 1, 'admin', '院长办公室', '/nursing/plan/status', '127.0.0.1', '内网IP', '{\"id\":141,\"status\":1}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 10:16:15', 17); +INSERT INTO `sys_oper_log` VALUES (483, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '院长办公室', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":141,\"planName\":\"4号\",\"projectPlans\":[{\"createBy\":\"1\",\"createTime\":\"2025-02-24 13:50:52\",\"executeCycle\":1,\"executeFrequency\":2,\"executeTime\":\"13:50:33\",\"id\":1754,\"params\":{},\"planId\":141,\"projectId\":5},{\"createBy\":\"1\",\"createTime\":\"2025-02-24 18:16:27\",\"executeCycle\":0,\"executeFrequency\":1,\"executeTime\":\"18:16:22\",\"id\":1756,\"params\":{},\"planId\":141,\"projectId\":2}],\"sortNo\":1,\"status\":1}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 10:16:26', 76); +INSERT INTO `sys_oper_log` VALUES (484, '护理计划', 1, 'com.zzyl.nursing.controller.NursingPlanController.add()', 'POST', 1, 'admin', '院长办公室', '/nursing/plan', '127.0.0.1', '内网IP', '{\"planName\":\"5号护理计划\",\"projectPlans\":[{\"createBy\":\"1\",\"createTime\":\"2025-02-24 18:16:49\",\"executeFrequency\":1,\"executeTime\":\"\",\"params\":{},\"planId\":142}],\"sortNo\":1,\"status\":1}', NULL, 1, 'com.zzyl.nursing.mapper.NursingProjectPlanMapper.insert (batch index #1) failed. Cause: java.sql.BatchUpdateException: Field \'project_id\' doesn\'t have a default value\n; Field \'project_id\' doesn\'t have a default value; nested exception is java.sql.BatchUpdateException: Field \'project_id\' doesn\'t have a default value', '2025-02-24 10:16:48', 95); +INSERT INTO `sys_oper_log` VALUES (485, '护理计划', 1, 'com.zzyl.nursing.controller.NursingPlanController.add()', 'POST', 1, 'admin', '院长办公室', '/nursing/plan', '127.0.0.1', '内网IP', '{\"planName\":\"5号护理计划\",\"projectPlans\":[{\"createBy\":\"1\",\"createTime\":\"2025-02-24 18:16:54\",\"executeFrequency\":1,\"executeTime\":\"\",\"params\":{},\"planId\":143}],\"sortNo\":8,\"status\":1}', NULL, 1, 'com.zzyl.nursing.mapper.NursingProjectPlanMapper.insert (batch index #1) failed. Cause: java.sql.BatchUpdateException: Field \'project_id\' doesn\'t have a default value\n; Field \'project_id\' doesn\'t have a default value; nested exception is java.sql.BatchUpdateException: Field \'project_id\' doesn\'t have a default value', '2025-02-24 10:16:53', 18); +INSERT INTO `sys_oper_log` VALUES (486, '护理计划', 1, 'com.zzyl.nursing.controller.NursingPlanController.add()', 'POST', 1, 'admin', '院长办公室', '/nursing/plan', '127.0.0.1', '内网IP', '{\"planName\":\"5号护理计划\",\"projectPlans\":[{\"createBy\":\"1\",\"createTime\":\"2025-02-24 18:18:32\",\"executeFrequency\":1,\"executeTime\":\"\",\"params\":{},\"planId\":144}],\"sortNo\":8,\"status\":1}', NULL, 1, 'com.zzyl.nursing.mapper.NursingProjectPlanMapper.insert (batch index #1) failed. Cause: java.sql.BatchUpdateException: Field \'project_id\' doesn\'t have a default value\n; Field \'project_id\' doesn\'t have a default value; nested exception is java.sql.BatchUpdateException: Field \'project_id\' doesn\'t have a default value', '2025-02-24 10:18:32', 178); +INSERT INTO `sys_oper_log` VALUES (487, '护理计划', 1, 'com.zzyl.nursing.controller.NursingPlanController.add()', 'POST', 1, 'admin', '院长办公室', '/nursing/plan', '127.0.0.1', '内网IP', '{\"planName\":\"5号护理计划\",\"projectPlans\":[{\"createBy\":\"1\",\"createTime\":\"2025-02-24 18:20:36\",\"executeFrequency\":1,\"executeTime\":\"\",\"params\":{},\"planId\":145}],\"sortNo\":8,\"status\":1}', NULL, 1, 'com.zzyl.nursing.mapper.NursingProjectPlanMapper.insert (batch index #1) failed. Cause: java.sql.BatchUpdateException: Field \'project_id\' doesn\'t have a default value\n; Field \'project_id\' doesn\'t have a default value; nested exception is java.sql.BatchUpdateException: Field \'project_id\' doesn\'t have a default value', '2025-02-24 10:20:35', 38008); +INSERT INTO `sys_oper_log` VALUES (488, '护理计划', 1, 'com.zzyl.nursing.controller.NursingPlanController.add()', 'POST', 1, 'admin', '院长办公室', '/nursing/plan', '127.0.0.1', '内网IP', '{\"planName\":\"5号护理计划\",\"projectPlans\":[{\"createBy\":\"1\",\"createTime\":\"2025-02-24 18:21:37\",\"executeTime\":\"\",\"params\":{},\"planId\":146}],\"sortNo\":8,\"status\":1}', NULL, 1, 'com.zzyl.nursing.mapper.NursingProjectPlanMapper.insert (batch index #1) failed. Cause: java.sql.BatchUpdateException: Field \'project_id\' doesn\'t have a default value\n; Field \'project_id\' doesn\'t have a default value; nested exception is java.sql.BatchUpdateException: Field \'project_id\' doesn\'t have a default value', '2025-02-24 10:21:36', 4981); +INSERT INTO `sys_oper_log` VALUES (489, '护理计划', 1, 'com.zzyl.nursing.controller.NursingPlanController.add()', 'POST', 1, 'admin', '院长办公室', '/nursing/plan', '127.0.0.1', '内网IP', '{\"planName\":\"5号\",\"projectPlans\":[{\"createBy\":\"1\",\"createTime\":\"2025-02-24 19:04:01\",\"executeCycle\":1,\"executeFrequency\":3,\"executeTime\":\"19:03:49\",\"id\":1757,\"params\":{},\"planId\":147,\"projectId\":2}],\"sortNo\":1,\"status\":1}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 11:04:00', 90); +INSERT INTO `sys_oper_log` VALUES (490, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.editStatus()', 'PUT', 1, 'admin', '院长办公室', '/nursing/plan/status', '127.0.0.1', '内网IP', '{\"id\":147,\"status\":0}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 11:04:04', 43); +INSERT INTO `sys_oper_log` VALUES (491, '护理计划', 3, 'com.zzyl.nursing.controller.NursingPlanController.remove()', 'DELETE', 1, 'admin', '院长办公室', '/nursing/plan/147', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 11:04:07', 28); +INSERT INTO `sys_oper_log` VALUES (492, '护理等级', 1, 'com.zzyl.nursing.controller.NursingLevelController.add()', 'POST', 1, 'admin', '院长办公室', '/nursing/level', '127.0.0.1', '内网IP', '{\"createBy\":\"1\",\"createTime\":\"2025-02-24 19:10:34\",\"description\":\"4号等级4号等级\",\"fee\":4500,\"id\":79,\"lplanId\":141,\"name\":\"4号等级\",\"params\":{}}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 11:10:33', 16); +INSERT INTO `sys_oper_log` VALUES (493, '护理等级', 2, 'com.zzyl.nursing.controller.NursingLevelController.edit()', 'PUT', 1, 'admin', '院长办公室', '/nursing/level', '127.0.0.1', '内网IP', '{\"createBy\":\"1\",\"createTime\":\"2025-02-24 19:10:34\",\"description\":\"4号等级4号等级\",\"fee\":4550,\"id\":79,\"lplanId\":141,\"name\":\"4-4号等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-24 19:10:49\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 11:10:48', 12); +INSERT INTO `sys_oper_log` VALUES (494, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.remove()', 'DELETE', 1, 'admin', '院长办公室', '/nursing/level/79', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 11:11:01', 10); +INSERT INTO `sys_oper_log` VALUES (495, '房型', 2, 'com.zzyl.nursing.controller.RoomTypeController.edit()', 'PUT', 1, 'admin', '院长办公室', '/elder/roomType', '127.0.0.1', '内网IP', '{\"id\":117,\"params\":{},\"status\":0,\"updateBy\":\"1\",\"updateTime\":\"2025-02-24 19:18:45\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 11:18:45', 47); +INSERT INTO `sys_oper_log` VALUES (496, '床位', 3, 'com.zzyl.nursing.controller.BedController.remove()', 'DELETE', 1, 'admin', '院长办公室', '/elder/bed/205', '127.0.0.1', '内网IP', '[205]', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 11:18:54', 34); +INSERT INTO `sys_oper_log` VALUES (497, '床位', 1, 'com.zzyl.nursing.controller.BedController.add()', 'POST', 1, 'admin', '院长办公室', '/elder/bed', '127.0.0.1', '内网IP', '{\"bedNumber\":\"110-2\",\"createBy\":\"1\",\"createTime\":\"2025-02-24 19:19:03\",\"id\":207,\"params\":{},\"roomId\":89,\"sort\":1}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 11:19:02', 29); +INSERT INTO `sys_oper_log` VALUES (498, '床位', 3, 'com.zzyl.nursing.controller.BedController.remove()', 'DELETE', 1, 'admin', '院长办公室', '/elder/bed/202', '127.0.0.1', '内网IP', '[202]', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 11:19:09', 11); +INSERT INTO `sys_oper_log` VALUES (499, '房间', 1, 'com.zzyl.nursing.controller.RoomController.add()', 'POST', 1, 'admin', '院长办公室', '/elder/room', '127.0.0.1', '内网IP', '{\"code\":\"111\",\"createBy\":\"1\",\"createTime\":\"2025-02-24 19:19:17\",\"floorId\":1,\"id\":91,\"params\":{},\"sort\":1,\"typeName\":\"标准双人间\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 11:19:16', 15); +INSERT INTO `sys_oper_log` VALUES (500, '床位', 1, 'com.zzyl.nursing.controller.BedController.add()', 'POST', 1, 'admin', '院长办公室', '/elder/bed', '127.0.0.1', '内网IP', '{\"bedNumber\":\"111-1\",\"createBy\":\"1\",\"createTime\":\"2025-02-24 19:19:24\",\"id\":208,\"params\":{},\"roomId\":91,\"sort\":1}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 11:19:23', 8); +INSERT INTO `sys_oper_log` VALUES (501, '床位', 1, 'com.zzyl.nursing.controller.BedController.add()', 'POST', 1, 'admin', '院长办公室', '/elder/bed', '127.0.0.1', '内网IP', '{\"bedNumber\":\"109-3\",\"createBy\":\"1\",\"createTime\":\"2025-02-24 19:19:50\",\"id\":209,\"params\":{},\"roomId\":81,\"sort\":3}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 11:19:49', 9); +INSERT INTO `sys_oper_log` VALUES (502, '床位', 2, 'com.zzyl.nursing.controller.BedController.edit()', 'PUT', 1, 'admin', '院长办公室', '/elder/bed', '127.0.0.1', '内网IP', '{\"bedNumber\":\"110-2\",\"id\":207,\"params\":{},\"roomId\":81,\"sort\":2,\"updateBy\":\"1\",\"updateTime\":\"2025-02-24 19:19:58\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 11:19:57', 29); +INSERT INTO `sys_oper_log` VALUES (503, '床位', 2, 'com.zzyl.nursing.controller.BedController.edit()', 'PUT', 1, 'admin', '院长办公室', '/elder/bed', '127.0.0.1', '内网IP', '{\"bedNumber\":\"110-2\",\"id\":207,\"params\":{},\"roomId\":81,\"sort\":2,\"updateBy\":\"1\",\"updateTime\":\"2025-02-24 19:20:12\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 11:20:11', 10); +INSERT INTO `sys_oper_log` VALUES (504, '床位', 3, 'com.zzyl.nursing.controller.BedController.remove()', 'DELETE', 1, 'admin', '院长办公室', '/elder/bed/207', '127.0.0.1', '内网IP', '[207]', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 11:20:14', 8); +INSERT INTO `sys_oper_log` VALUES (505, '床位', 1, 'com.zzyl.nursing.controller.BedController.add()', 'POST', 1, 'admin', '院长办公室', '/elder/bed', '127.0.0.1', '内网IP', '{\"bedNumber\":\"110-2\",\"createBy\":\"1\",\"createTime\":\"2025-02-24 19:20:21\",\"id\":207,\"params\":{},\"roomId\":89,\"sort\":2}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-24 11:20:21', 8); +INSERT INTO `sys_oper_log` VALUES (506, '护理等级', 2, 'com.zzyl.nursing.controller.NursingLevelController.edit()', 'PUT', 1, 'admin', '院长办公室', '/nursing/level', '127.0.0.1', '内网IP', '{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3100,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:03:33\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-25 01:03:33', 55); +INSERT INTO `sys_oper_log` VALUES (507, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '院长办公室', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":141,\"status\":0}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-25 01:09:46', 43); +INSERT INTO `sys_oper_log` VALUES (508, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '院长办公室', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":141,\"status\":1}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-25 01:09:49', 20); +INSERT INTO `sys_oper_log` VALUES (509, '护理等级', 2, 'com.zzyl.nursing.controller.NursingLevelController.edit()', 'PUT', 1, 'admin', '院长办公室', '/nursing/level', '127.0.0.1', '内网IP', '{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:10:02\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-25 01:10:01', 10); +INSERT INTO `sys_oper_log` VALUES (510, '护理等级', 1, 'com.zzyl.nursing.controller.NursingLevelController.add()', 'POST', 1, 'admin', '院长办公室', '/nursing/level', '127.0.0.1', '内网IP', '{\"createBy\":\"1\",\"createTime\":\"2025-02-25 09:16:54\",\"description\":\"4号4号\",\"fee\":2444,\"id\":80,\"lplanId\":141,\"name\":\"4号\",\"params\":{}}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-25 01:16:53', 29); +INSERT INTO `sys_oper_log` VALUES (511, '护理等级', 2, 'com.zzyl.nursing.controller.NursingLevelController.edit()', 'PUT', 1, 'admin', '院长办公室', '/nursing/level', '127.0.0.1', '内网IP', '{\"createBy\":\"1\",\"createTime\":\"2025-02-25 09:16:54\",\"description\":\"4号4号\",\"fee\":2444,\"id\":80,\"lplanId\":141,\"name\":\"4号2\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:16:59\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-25 01:16:58', 15); +INSERT INTO `sys_oper_log` VALUES (512, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.remove()', 'DELETE', 1, 'admin', '院长办公室', '/nursing/level/80', '127.0.0.1', '内网IP', '[80]', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-25 01:17:00', 43); +INSERT INTO `sys_oper_log` VALUES (513, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理计划\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:05\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:10:02\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-25 01:24:09', 64); +INSERT INTO `sys_oper_log` VALUES (514, '护理等级', 2, 'com.zzyl.nursing.controller.NursingLevelController.edit()', 'PUT', 1, 'admin', '院长办公室', '/nursing/level', '127.0.0.1', '内网IP', '{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":0,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:27:18\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-25 01:27:18', 60); +INSERT INTO `sys_oper_log` VALUES (515, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理计划\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:05\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-25 01:28:37', 17); +INSERT INTO `sys_oper_log` VALUES (516, '护理等级', 2, 'com.zzyl.nursing.controller.NursingLevelController.edit()', 'PUT', 1, 'admin', '院长办公室', '/nursing/level', '127.0.0.1', '内网IP', '{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:50\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-25 01:28:50', 13); +INSERT INTO `sys_oper_log` VALUES (517, '代码生成', 6, 'com.zzyl.generator.controller.GenController.importTableSave()', 'POST', 1, 'admin', '院长办公室', '/tool/gen/importTable', '127.0.0.1', '内网IP', '{\"tables\":\"contract,check_in,check_in_config\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-25 01:29:24', 516); +INSERT INTO `sys_oper_log` VALUES (518, '代码生成', 6, 'com.zzyl.generator.controller.GenController.importTableSave()', 'POST', 1, 'admin', '院长办公室', '/tool/gen/importTable', '127.0.0.1', '内网IP', '{\"tables\":\"elder\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-25 01:29:45', 109); +INSERT INTO `sys_oper_log` VALUES (519, '代码生成', 2, 'com.zzyl.generator.controller.GenController.editSave()', 'PUT', 1, 'admin', '院长办公室', '/tool/gen', '127.0.0.1', '内网IP', '{\"businessName\":\"checkIn\",\"className\":\"CheckIn\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键ID\",\"columnId\":273,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2025-02-25 01:29:24\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":19,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"ElderName\",\"columnComment\":\"老人姓名\",\"columnId\":274,\"columnName\":\"elder_name\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2025-02-25 01:29:24\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"elderName\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":19,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"ElderId\",\"columnComment\":\"老人ID\",\"columnId\":275,\"columnName\":\"elder_id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2025-02-25 01:29:24\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"elderId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":19,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"IdCardNo\",\"columnComment\":\"身份证号\",\"columnId\":276,\"columnName\":\"id_card_no\",\"columnType\":\"char(18)\",\"createBy\":\"admin\",\"createTime\":\"2025-02-25 01:29:24\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-25 01:33:20', 165); +INSERT INTO `sys_oper_log` VALUES (520, '代码生成', 2, 'com.zzyl.generator.controller.GenController.editSave()', 'PUT', 1, 'admin', '院长办公室', '/tool/gen', '127.0.0.1', '内网IP', '{\"businessName\":\"checkInConfig\",\"className\":\"CheckInConfig\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键ID\",\"columnId\":288,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2025-02-25 01:29:24\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":20,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"CheckInId\",\"columnComment\":\"入住表ID\",\"columnId\":289,\"columnName\":\"check_in_id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2025-02-25 01:29:24\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"checkInId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":20,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"NursingLevelId\",\"columnComment\":\"护理等级ID\",\"columnId\":290,\"columnName\":\"nursing_level_id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2025-02-25 01:29:24\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"nursingLevelId\",\"javaType\":\"Long\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":20,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"NursingLevelName\",\"columnComment\":\"护理等级名称\",\"columnId\":291,\"columnName\":\"nursing_level_name\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2025-02-25 01:29:24\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"i', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-25 01:34:07', 121); +INSERT INTO `sys_oper_log` VALUES (521, '代码生成', 2, 'com.zzyl.generator.controller.GenController.editSave()', 'PUT', 1, 'admin', '院长办公室', '/tool/gen', '127.0.0.1', '内网IP', '{\"businessName\":\"contract\",\"className\":\"Contract\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键ID\",\"columnId\":306,\"columnName\":\"id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2025-02-25 01:29:24\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Integer\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":21,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"ElderId\",\"columnComment\":\"老人ID\",\"columnId\":307,\"columnName\":\"elder_id\",\"columnType\":\"int\",\"createBy\":\"admin\",\"createTime\":\"2025-02-25 01:29:24\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"elderId\",\"javaType\":\"Integer\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":true,\"sort\":2,\"superColumn\":false,\"tableId\":21,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"ContractName\",\"columnComment\":\"合同名称\",\"columnId\":308,\"columnName\":\"contract_name\",\"columnType\":\"varchar(100)\",\"createBy\":\"admin\",\"createTime\":\"2025-02-25 01:29:24\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"1\",\"javaField\":\"contractName\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":true,\"sort\":3,\"superColumn\":false,\"tableId\":21,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"ContractNumber\",\"columnComment\":\"合同编号\",\"columnId\":309,\"columnName\":\"contract_number\",\"columnType\":\"varchar(50)\",\"createBy\":\"admin\",\"createTime\":\"2025-02-25 01:29:24\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-25 01:34:58', 158); +INSERT INTO `sys_oper_log` VALUES (522, '代码生成', 2, 'com.zzyl.generator.controller.GenController.editSave()', 'PUT', 1, 'admin', '院长办公室', '/tool/gen', '127.0.0.1', '内网IP', '{\"businessName\":\"elder\",\"className\":\"Elder\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"id\",\"columnId\":327,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2025-02-25 01:29:45\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":22,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"Name\",\"columnComment\":\"名称\",\"columnId\":328,\"columnName\":\"name\",\"columnType\":\"varchar(255)\",\"createBy\":\"admin\",\"createTime\":\"2025-02-25 01:29:45\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"name\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":false,\"sort\":2,\"superColumn\":false,\"tableId\":22,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"Image\",\"columnComment\":\"图片\",\"columnId\":329,\"columnName\":\"image\",\"columnType\":\"varchar(255)\",\"createBy\":\"admin\",\"createTime\":\"2025-02-25 01:29:45\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"imageUpload\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"image\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":false,\"sort\":3,\"superColumn\":false,\"tableId\":22,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"IdCardNo\",\"columnComment\":\"身份证号\",\"columnId\":330,\"columnName\":\"id_card_no\",\"columnType\":\"varchar(20)\",\"createBy\":\"admin\",\"createTime\":\"2025-02-25 01:29:45\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"idCardNo\",', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-25 01:35:12', 132); +INSERT INTO `sys_oper_log` VALUES (523, '代码生成', 8, 'com.zzyl.generator.controller.GenController.batchGenCode()', 'GET', 1, 'admin', '院长办公室', '/tool/gen/batchGenCode', '127.0.0.1', '内网IP', '{\"tables\":\"check_in,check_in_config,contract,elder\"}', NULL, 0, NULL, '2025-02-25 01:35:21', 656); +INSERT INTO `sys_oper_log` VALUES (524, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理计划\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:05\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-25 01:42:10', 78); +INSERT INTO `sys_oper_log` VALUES (525, '护理等级', 2, 'com.zzyl.nursing.controller.NursingLevelController.edit()', 'PUT', 1, 'admin', '院长办公室', '/nursing/level', '127.0.0.1', '内网IP', '{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-25 01:42:33', 46); +INSERT INTO `sys_oper_log` VALUES (526, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-25 02:17:30', 80); +INSERT INTO `sys_oper_log` VALUES (527, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-25 02:56:52', 96); +INSERT INTO `sys_oper_log` VALUES (528, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-25 02:57:15', 9); +INSERT INTO `sys_oper_log` VALUES (529, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-25 02:58:38', 9); +INSERT INTO `sys_oper_log` VALUES (530, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-25 02:58:40', 7); +INSERT INTO `sys_oper_log` VALUES (531, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-25 02:59:52', 11); +INSERT INTO `sys_oper_log` VALUES (532, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-25 03:00:04', 7); +INSERT INTO `sys_oper_log` VALUES (533, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-25 03:00:11', 6); +INSERT INTO `sys_oper_log` VALUES (534, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-25 03:04:48', 7); +INSERT INTO `sys_oper_log` VALUES (535, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-25 03:26:19', 51); +INSERT INTO `sys_oper_log` VALUES (536, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-25 03:26:20', 14); +INSERT INTO `sys_oper_log` VALUES (537, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-25 03:26:23', 9); +INSERT INTO `sys_oper_log` VALUES (538, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-25 03:26:41', 9); +INSERT INTO `sys_oper_log` VALUES (539, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-25 03:41:32', 34); +INSERT INTO `sys_oper_log` VALUES (540, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-25 03:41:35', 15); +INSERT INTO `sys_oper_log` VALUES (541, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-25 08:14:01', 1268); +INSERT INTO `sys_oper_log` VALUES (542, '入住表', 1, 'com.zzyl.nursing.controller.CheckInController.apply()', 'POST', 1, 'admin', '院长办公室', '/nursing/checkIn/apply', '127.0.0.1', '内网IP', '{\"checkInConfigDto\":{\"bedFee\":6000.00,\"bedId\":45,\"code\":\"502\",\"deposit\":3000,\"endDate\":\"2025-03-26 00:00:00\",\"feeEndDate\":\"2025-03-26 00:00:00\",\"feeStartDate\":\"2025-02-26 00:00:00\",\"floorId\":5,\"floorName\":\"5楼\",\"governmentSubsidy\":3,\"insurancePayment\":2,\"nursingFee\":1500,\"nursingLevelId\":76,\"nursingLevelName\":\"2号护理等级\",\"otherFees\":1,\"roomId\":31,\"startDate\":\"2025-02-26 00:00:00\"},\"checkInContractDto\":{\"contractName\":\"老刘养老院入住合同\",\"signDate\":\"2025-02-26 00:00:00\",\"thirdPartyName\":\"小刘一\",\"thirdPartyPhone\":\"15238841235\"},\"checkInElderDto\":{\"address\":\"测试一\",\"age\":65,\"birthday\":\"1960-03-14\",\"idCardNationalEmblemImg\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/25/363080aada2844ce900d48a8c093cd3d.jpg\",\"idCardNo\":\"430123196003140736\",\"idCardPortraitImg\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/25/18b0626118214e6ea3043d1cf8a9a69d.jpg\",\"image\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/25/97fd681b13c8494cb5f3fafbdaa14bf7.png\",\"name\":\"老刘\",\"phone\":\"15723517412\",\"sex\":1},\"elderFamilyDtoList\":[{\"kinship\":\"0\",\"name\":\"小刘一\",\"phone\":\"15238841235\"},{\"kinship\":\"2\",\"name\":\"小刘二\",\"phone\":\"15238841236\"}]}', NULL, 1, '', '2025-02-25 08:18:38', 214); +INSERT INTO `sys_oper_log` VALUES (543, '入住表', 1, 'com.zzyl.nursing.controller.CheckInController.apply()', 'POST', 1, 'admin', '院长办公室', '/nursing/checkIn/apply', '127.0.0.1', '内网IP', '{\"checkInConfigDto\":{\"bedFee\":6000.00,\"bedId\":45,\"code\":\"502\",\"deposit\":3000,\"endDate\":\"2025-03-26 00:00:00\",\"feeEndDate\":\"2025-03-26 00:00:00\",\"feeStartDate\":\"2025-02-26 00:00:00\",\"floorId\":5,\"floorName\":\"5楼\",\"governmentSubsidy\":3,\"insurancePayment\":2,\"nursingFee\":1500,\"nursingLevelId\":76,\"nursingLevelName\":\"2号护理等级\",\"otherFees\":1,\"roomId\":31,\"startDate\":\"2025-02-26 00:00:00\"},\"checkInContractDto\":{\"contractName\":\"老刘养老院入住合同\",\"signDate\":\"2025-02-26 00:00:00\",\"thirdPartyName\":\"小刘一\",\"thirdPartyPhone\":\"15238841235\"},\"checkInElderDto\":{\"address\":\"测试一\",\"age\":65,\"birthday\":\"1960-03-14\",\"idCardNationalEmblemImg\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/25/363080aada2844ce900d48a8c093cd3d.jpg\",\"idCardNo\":\"430123196003140736\",\"idCardPortraitImg\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/25/18b0626118214e6ea3043d1cf8a9a69d.jpg\",\"image\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/25/97fd681b13c8494cb5f3fafbdaa14bf7.png\",\"name\":\"老刘\",\"phone\":\"15723517412\",\"sex\":1},\"elderFamilyDtoList\":[{\"kinship\":\"0\",\"name\":\"小刘一\",\"phone\":\"15238841235\"},{\"kinship\":\"2\",\"name\":\"小刘二\",\"phone\":\"15238841236\"}]}', NULL, 1, '\r\n### Error updating database. Cause: java.sql.SQLException: Field \'update_by\' doesn\'t have a default value\r\n### The error may exist in com/zzyl/nursing/mapper/CheckInConfigMapper.java (best guess)\r\n### The error may involve com.zzyl.nursing.mapper.CheckInConfigMapper.insert-Inline\r\n### The error occurred while setting parameters\r\n### SQL: INSERT INTO check_in_config ( check_in_id, nursing_level_id, nursing_level_name, fee_start_date, fee_end_date, deposit, nursing_fee, bed_fee, insurance_payment, government_subsidy, other_fees, sort_order, create_by, create_time ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )\r\n### Cause: java.sql.SQLException: Field \'update_by\' doesn\'t have a default value\n; Field \'update_by\' doesn\'t have a default value; nested exception is java.sql.SQLException: Field \'update_by\' doesn\'t have a default value', '2025-02-25 08:23:03', 468); +INSERT INTO `sys_oper_log` VALUES (544, '入住表', 1, 'com.zzyl.nursing.controller.CheckInController.apply()', 'POST', 1, 'admin', '院长办公室', '/nursing/checkIn/apply', '127.0.0.1', '内网IP', '{\"checkInConfigDto\":{\"bedFee\":6000.00,\"bedId\":45,\"code\":\"502\",\"deposit\":3000,\"endDate\":\"2025-03-26 00:00:00\",\"feeEndDate\":\"2025-03-26 00:00:00\",\"feeStartDate\":\"2025-02-26 00:00:00\",\"floorId\":5,\"floorName\":\"5楼\",\"governmentSubsidy\":3,\"insurancePayment\":2,\"nursingFee\":1500,\"nursingLevelId\":76,\"nursingLevelName\":\"2号护理等级\",\"otherFees\":1,\"roomId\":31,\"startDate\":\"2025-02-26 00:00:00\"},\"checkInContractDto\":{\"contractName\":\"老刘养老院入住合同\",\"signDate\":\"2025-02-26 00:00:00\",\"thirdPartyName\":\"小刘一\",\"thirdPartyPhone\":\"15238841235\"},\"checkInElderDto\":{\"address\":\"测试一\",\"age\":65,\"birthday\":\"1960-03-14\",\"idCardNationalEmblemImg\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/25/363080aada2844ce900d48a8c093cd3d.jpg\",\"idCardNo\":\"430123196003140736\",\"idCardPortraitImg\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/25/18b0626118214e6ea3043d1cf8a9a69d.jpg\",\"image\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/25/97fd681b13c8494cb5f3fafbdaa14bf7.png\",\"name\":\"老刘\",\"phone\":\"15723517412\",\"sex\":1},\"elderFamilyDtoList\":[{\"kinship\":\"0\",\"name\":\"小刘一\",\"phone\":\"15238841235\"},{\"kinship\":\"2\",\"name\":\"小刘二\",\"phone\":\"15238841236\"}]}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-25 08:23:56', 66); +INSERT INTO `sys_oper_log` VALUES (545, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-25 08:30:01', 108); +INSERT INTO `sys_oper_log` VALUES (546, '入住表', 1, 'com.zzyl.nursing.controller.CheckInController.apply()', 'POST', 1, 'admin', '院长办公室', '/nursing/checkIn/apply', '127.0.0.1', '内网IP', '{\"checkInConfigDto\":{\"bedFee\":6000.00,\"bedId\":55,\"code\":\"601\",\"deposit\":3000,\"endDate\":\"2025-03-27 00:00:00\",\"feeEndDate\":\"2025-03-26 00:00:00\",\"feeStartDate\":\"2025-02-26 00:00:00\",\"floorId\":6,\"floorName\":\"6楼\",\"governmentSubsidy\":6,\"insurancePayment\":5,\"nursingFee\":3200,\"nursingLevelId\":78,\"nursingLevelName\":\"3号护理等级\",\"otherFees\":4,\"roomId\":37,\"startDate\":\"2025-02-27 00:00:00\"},\"checkInContractDto\":{\"contractName\":\"光头强入住养老院合同\",\"signDate\":\"2025-02-26 00:00:00\",\"thirdPartyName\":\"熊大\",\"thirdPartyPhone\":\"13568560836\"},\"checkInElderDto\":{\"address\":\"狗熊岭\",\"age\":64,\"birthday\":\"1961-03-14\",\"idCardNationalEmblemImg\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/25/93077f4941ee4a73aab63812f963e24f.jpg\",\"idCardNo\":\"410231196103140736\",\"idCardPortraitImg\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/25/4f7e4776987b4502a07003eec01da4e8.jpg\",\"image\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/25/ac18ca5f769c404d99cab5b16981c75e.png\",\"name\":\"光头强\",\"phone\":\"15734907312\",\"sex\":1},\"elderFamilyDtoList\":[{\"kinship\":\"3\",\"name\":\"熊大\",\"phone\":\"13568560836\"},{\"kinship\":\"3\",\"name\":\"熊二\",\"phone\":\"15762073711\"}]}', NULL, 1, '\r\n### Error updating database. Cause: java.sql.SQLException: Field \'contract_name\' doesn\'t have a default value\r\n### The error may exist in com/zzyl/nursing/mapper/ContractMapper.java (best guess)\r\n### The error may involve com.zzyl.nursing.mapper.ContractMapper.insert-Inline\r\n### The error occurred while setting parameters\r\n### SQL: INSERT INTO contract ( elder_id, contract_number, elder_name, start_date, end_date, status, sort_order, create_by, create_time, remark ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )\r\n### Cause: java.sql.SQLException: Field \'contract_name\' doesn\'t have a default value\n; Field \'contract_name\' doesn\'t have a default value; nested exception is java.sql.SQLException: Field \'contract_name\' doesn\'t have a default value', '2025-02-25 08:32:46', 74); +INSERT INTO `sys_oper_log` VALUES (547, '入住表', 1, 'com.zzyl.nursing.controller.CheckInController.apply()', 'POST', 1, 'admin', '院长办公室', '/nursing/checkIn/apply', '127.0.0.1', '内网IP', '{\"checkInConfigDto\":{\"bedFee\":6000.00,\"bedId\":55,\"code\":\"601\",\"deposit\":3000,\"endDate\":\"2025-03-27 00:00:00\",\"feeEndDate\":\"2025-03-26 00:00:00\",\"feeStartDate\":\"2025-02-26 00:00:00\",\"floorId\":6,\"floorName\":\"6楼\",\"governmentSubsidy\":6,\"insurancePayment\":5,\"nursingFee\":3200,\"nursingLevelId\":78,\"nursingLevelName\":\"3号护理等级\",\"otherFees\":4,\"roomId\":37,\"startDate\":\"2025-02-27 00:00:00\"},\"checkInContractDto\":{\"contractName\":\"光头强入住养老院合同\",\"signDate\":\"2025-02-26 00:00:00\",\"thirdPartyName\":\"熊大\",\"thirdPartyPhone\":\"13568560836\"},\"checkInElderDto\":{\"address\":\"狗熊岭\",\"age\":64,\"birthday\":\"1961-03-14\",\"idCardNationalEmblemImg\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/25/93077f4941ee4a73aab63812f963e24f.jpg\",\"idCardNo\":\"410231196103140736\",\"idCardPortraitImg\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/25/4f7e4776987b4502a07003eec01da4e8.jpg\",\"image\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/25/ac18ca5f769c404d99cab5b16981c75e.png\",\"name\":\"光头强\",\"phone\":\"15734907312\",\"sex\":1},\"elderFamilyDtoList\":[{\"kinship\":\"3\",\"name\":\"熊大\",\"phone\":\"13568560836\"},{\"kinship\":\"3\",\"name\":\"熊二\",\"phone\":\"15762073711\"}]}', NULL, 1, '\r\n### Error updating database. Cause: java.sql.SQLException: Field \'contract_name\' doesn\'t have a default value\r\n### The error may exist in com/zzyl/nursing/mapper/ContractMapper.java (best guess)\r\n### The error may involve com.zzyl.nursing.mapper.ContractMapper.insert-Inline\r\n### The error occurred while setting parameters\r\n### SQL: INSERT INTO contract ( elder_id, contract_number, elder_name, start_date, end_date, status, sort_order, create_by, create_time, remark ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )\r\n### Cause: java.sql.SQLException: Field \'contract_name\' doesn\'t have a default value\n; Field \'contract_name\' doesn\'t have a default value; nested exception is java.sql.SQLException: Field \'contract_name\' doesn\'t have a default value', '2025-02-25 08:33:50', 55); +INSERT INTO `sys_oper_log` VALUES (548, '入住表', 1, 'com.zzyl.nursing.controller.CheckInController.apply()', 'POST', 1, 'admin', '院长办公室', '/nursing/checkIn/apply', '127.0.0.1', '内网IP', '{\"checkInConfigDto\":{\"bedFee\":6000.00,\"bedId\":55,\"code\":\"601\",\"deposit\":3000,\"endDate\":\"2025-03-27 00:00:00\",\"feeEndDate\":\"2025-03-26 00:00:00\",\"feeStartDate\":\"2025-02-26 00:00:00\",\"floorId\":6,\"floorName\":\"6楼\",\"governmentSubsidy\":6,\"insurancePayment\":5,\"nursingFee\":3200,\"nursingLevelId\":78,\"nursingLevelName\":\"3号护理等级\",\"otherFees\":4,\"roomId\":37,\"startDate\":\"2025-02-27 00:00:00\"},\"checkInContractDto\":{\"contractName\":\"光头强入住养老院合同\",\"signDate\":\"2025-02-26 00:00:00\",\"thirdPartyName\":\"熊大\",\"thirdPartyPhone\":\"13568560836\"},\"checkInElderDto\":{\"address\":\"狗熊岭\",\"age\":64,\"birthday\":\"1961-03-14\",\"idCardNationalEmblemImg\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/25/93077f4941ee4a73aab63812f963e24f.jpg\",\"idCardNo\":\"410231196103140736\",\"idCardPortraitImg\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/25/4f7e4776987b4502a07003eec01da4e8.jpg\",\"image\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/25/ac18ca5f769c404d99cab5b16981c75e.png\",\"name\":\"光头强\",\"phone\":\"15734907312\",\"sex\":1},\"elderFamilyDtoList\":[{\"kinship\":\"3\",\"name\":\"熊大\",\"phone\":\"13568560836\"},{\"kinship\":\"3\",\"name\":\"熊二\",\"phone\":\"15762073711\"}]}', NULL, 1, '\r\n### Error updating database. Cause: java.sql.SQLException: Field \'agreement_path\' doesn\'t have a default value\r\n### The error may exist in com/zzyl/nursing/mapper/ContractMapper.java (best guess)\r\n### The error may involve com.zzyl.nursing.mapper.ContractMapper.insert-Inline\r\n### The error occurred while setting parameters\r\n### SQL: INSERT INTO contract ( elder_id, contract_name, contract_number, third_party_phone, third_party_name, elder_name, start_date, end_date, status, sign_date, sort_order, create_by, create_time, remark ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )\r\n### Cause: java.sql.SQLException: Field \'agreement_path\' doesn\'t have a default value\n; Field \'agreement_path\' doesn\'t have a default value; nested exception is java.sql.SQLException: Field \'agreement_path\' doesn\'t have a default value', '2025-02-25 08:35:43', 310); +INSERT INTO `sys_oper_log` VALUES (549, '入住表', 1, 'com.zzyl.nursing.controller.CheckInController.apply()', 'POST', 1, 'admin', '院长办公室', '/nursing/checkIn/apply', '127.0.0.1', '内网IP', '{\"checkInConfigDto\":{\"bedFee\":6000.00,\"bedId\":55,\"code\":\"601\",\"deposit\":3000,\"endDate\":\"2025-03-27 00:00:00\",\"feeEndDate\":\"2025-03-26 00:00:00\",\"feeStartDate\":\"2025-02-26 00:00:00\",\"floorId\":6,\"floorName\":\"6楼\",\"governmentSubsidy\":6,\"insurancePayment\":5,\"nursingFee\":3200,\"nursingLevelId\":78,\"nursingLevelName\":\"3号护理等级\",\"otherFees\":4,\"roomId\":37,\"startDate\":\"2025-02-27 00:00:00\"},\"checkInContractDto\":{\"contractName\":\"光头强入住养老院合同\",\"signDate\":\"2025-02-26 00:00:00\",\"thirdPartyName\":\"熊大\",\"thirdPartyPhone\":\"13568560836\"},\"checkInElderDto\":{\"address\":\"狗熊岭\",\"age\":64,\"birthday\":\"1961-03-14\",\"idCardNationalEmblemImg\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/25/93077f4941ee4a73aab63812f963e24f.jpg\",\"idCardNo\":\"410231196103140736\",\"idCardPortraitImg\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/25/4f7e4776987b4502a07003eec01da4e8.jpg\",\"image\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/25/ac18ca5f769c404d99cab5b16981c75e.png\",\"name\":\"光头强\",\"phone\":\"15734907312\",\"sex\":1},\"elderFamilyDtoList\":[{\"kinship\":\"3\",\"name\":\"熊大\",\"phone\":\"13568560836\"},{\"kinship\":\"3\",\"name\":\"熊二\",\"phone\":\"15762073711\"}]}', NULL, 1, '\r\n### Error updating database. Cause: java.sql.SQLException: Field \'agreement_path\' doesn\'t have a default value\r\n### The error may exist in com/zzyl/nursing/mapper/ContractMapper.java (best guess)\r\n### The error may involve com.zzyl.nursing.mapper.ContractMapper.insert-Inline\r\n### The error occurred while setting parameters\r\n### SQL: INSERT INTO contract ( elder_id, contract_name, contract_number, third_party_phone, third_party_name, elder_name, start_date, end_date, status, sign_date, sort_order, create_by, create_time, remark ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )\r\n### Cause: java.sql.SQLException: Field \'agreement_path\' doesn\'t have a default value\n; Field \'agreement_path\' doesn\'t have a default value; nested exception is java.sql.SQLException: Field \'agreement_path\' doesn\'t have a default value', '2025-02-25 08:38:34', 51); +INSERT INTO `sys_oper_log` VALUES (550, '入住表', 1, 'com.zzyl.nursing.controller.CheckInController.apply()', 'POST', 1, 'admin', '院长办公室', '/nursing/checkIn/apply', '127.0.0.1', '内网IP', '{\"checkInConfigDto\":{\"bedFee\":6000.00,\"bedId\":55,\"code\":\"601\",\"deposit\":3000,\"endDate\":\"2025-03-27 00:00:00\",\"feeEndDate\":\"2025-03-26 00:00:00\",\"feeStartDate\":\"2025-02-26 00:00:00\",\"floorId\":6,\"floorName\":\"6楼\",\"governmentSubsidy\":6,\"insurancePayment\":5,\"nursingFee\":3200,\"nursingLevelId\":78,\"nursingLevelName\":\"3号护理等级\",\"otherFees\":4,\"roomId\":37,\"startDate\":\"2025-02-27 00:00:00\"},\"checkInContractDto\":{\"contractName\":\"光头强入住养老院合同\",\"signDate\":\"2025-02-26 00:00:00\",\"thirdPartyName\":\"熊大\",\"thirdPartyPhone\":\"13568560836\"},\"checkInElderDto\":{\"address\":\"狗熊岭\",\"age\":64,\"birthday\":\"1961-03-14\",\"idCardNationalEmblemImg\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/25/93077f4941ee4a73aab63812f963e24f.jpg\",\"idCardNo\":\"410231196103140736\",\"idCardPortraitImg\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/25/4f7e4776987b4502a07003eec01da4e8.jpg\",\"image\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/25/ac18ca5f769c404d99cab5b16981c75e.png\",\"name\":\"光头强\",\"phone\":\"15734907312\",\"sex\":1},\"elderFamilyDtoList\":[{\"kinship\":\"3\",\"name\":\"熊大\",\"phone\":\"13568560836\"},{\"kinship\":\"3\",\"name\":\"熊二\",\"phone\":\"15762073711\"}]}', NULL, 1, '\r\n### Error updating database. Cause: java.sql.SQLException: Field \'agreement_path\' doesn\'t have a default value\r\n### The error may exist in com/zzyl/nursing/mapper/ContractMapper.java (best guess)\r\n### The error may involve com.zzyl.nursing.mapper.ContractMapper.insert-Inline\r\n### The error occurred while setting parameters\r\n### SQL: INSERT INTO contract ( elder_id, contract_name, contract_number, third_party_phone, third_party_name, elder_name, start_date, end_date, status, sign_date, sort_order, create_by, create_time, remark ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )\r\n### Cause: java.sql.SQLException: Field \'agreement_path\' doesn\'t have a default value\n; Field \'agreement_path\' doesn\'t have a default value; nested exception is java.sql.SQLException: Field \'agreement_path\' doesn\'t have a default value', '2025-02-25 08:39:38', 47); +INSERT INTO `sys_oper_log` VALUES (551, '入住表', 1, 'com.zzyl.nursing.controller.CheckInController.apply()', 'POST', 1, 'admin', '院长办公室', '/nursing/checkIn/apply', '127.0.0.1', '内网IP', '{\"checkInConfigDto\":{\"bedFee\":6000.00,\"bedId\":55,\"code\":\"601\",\"deposit\":3000,\"endDate\":\"2025-03-27 00:00:00\",\"feeEndDate\":\"2025-03-26 00:00:00\",\"feeStartDate\":\"2025-02-26 00:00:00\",\"floorId\":6,\"floorName\":\"6楼\",\"governmentSubsidy\":6,\"insurancePayment\":5,\"nursingFee\":3200,\"nursingLevelId\":78,\"nursingLevelName\":\"3号护理等级\",\"otherFees\":4,\"roomId\":37,\"startDate\":\"2025-02-27 00:00:00\"},\"checkInContractDto\":{\"contractName\":\"光头强入住养老院合同\",\"signDate\":\"2025-02-26 00:00:00\",\"thirdPartyName\":\"熊大\",\"thirdPartyPhone\":\"13568560836\"},\"checkInElderDto\":{\"address\":\"狗熊岭\",\"age\":64,\"birthday\":\"1961-03-14\",\"idCardNationalEmblemImg\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/25/93077f4941ee4a73aab63812f963e24f.jpg\",\"idCardNo\":\"410231196103140736\",\"idCardPortraitImg\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/25/4f7e4776987b4502a07003eec01da4e8.jpg\",\"image\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/25/ac18ca5f769c404d99cab5b16981c75e.png\",\"name\":\"光头强\",\"phone\":\"15734907312\",\"sex\":1},\"elderFamilyDtoList\":[{\"kinship\":\"3\",\"name\":\"熊大\",\"phone\":\"13568560836\"},{\"kinship\":\"3\",\"name\":\"熊二\",\"phone\":\"15762073711\"}]}', NULL, 1, '\r\n### Error updating database. Cause: java.sql.SQLException: Field \'agreement_path\' doesn\'t have a default value\r\n### The error may exist in com/zzyl/nursing/mapper/ContractMapper.java (best guess)\r\n### The error may involve com.zzyl.nursing.mapper.ContractMapper.insert-Inline\r\n### The error occurred while setting parameters\r\n### SQL: INSERT INTO contract ( elder_id, contract_name, contract_number, third_party_phone, third_party_name, elder_name, start_date, end_date, status, sign_date, sort_order, create_by, create_time, remark ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )\r\n### Cause: java.sql.SQLException: Field \'agreement_path\' doesn\'t have a default value\n; Field \'agreement_path\' doesn\'t have a default value; nested exception is java.sql.SQLException: Field \'agreement_path\' doesn\'t have a default value', '2025-02-25 08:40:03', 53); +INSERT INTO `sys_oper_log` VALUES (552, '入住表', 1, 'com.zzyl.nursing.controller.CheckInController.apply()', 'POST', 1, 'admin', '院长办公室', '/nursing/checkIn/apply', '127.0.0.1', '内网IP', '{\"checkInConfigDto\":{\"bedFee\":6000.00,\"bedId\":55,\"code\":\"601\",\"deposit\":3000,\"endDate\":\"2025-03-27 00:00:00\",\"feeEndDate\":\"2025-03-26 00:00:00\",\"feeStartDate\":\"2025-02-26 00:00:00\",\"floorId\":6,\"floorName\":\"6楼\",\"governmentSubsidy\":6,\"insurancePayment\":5,\"nursingFee\":3200,\"nursingLevelId\":78,\"nursingLevelName\":\"3号护理等级\",\"otherFees\":4,\"roomId\":37,\"startDate\":\"2025-02-27 00:00:00\"},\"checkInContractDto\":{\"agreementPath\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/25/1c2111abe3b945f5b8d81158a4982769.pdf\",\"contractName\":\"光头强入住养老院合同\",\"signDate\":\"2025-02-26 00:00:00\",\"thirdPartyName\":\"熊大\",\"thirdPartyPhone\":\"13568560836\"},\"checkInElderDto\":{\"address\":\"狗熊岭\",\"age\":64,\"birthday\":\"1961-03-14\",\"idCardNationalEmblemImg\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/25/93077f4941ee4a73aab63812f963e24f.jpg\",\"idCardNo\":\"410231196103140736\",\"idCardPortraitImg\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/25/4f7e4776987b4502a07003eec01da4e8.jpg\",\"image\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/25/ac18ca5f769c404d99cab5b16981c75e.png\",\"name\":\"光头强\",\"phone\":\"15734907312\",\"sex\":1},\"elderFamilyDtoList\":[{\"kinship\":\"3\",\"name\":\"熊大\",\"phone\":\"13568560836\"},{\"kinship\":\"3\",\"name\":\"熊二\",\"phone\":\"15762073711\"}]}', NULL, 1, '\r\n### Error updating database. Cause: java.sql.SQLException: Field \'update_by\' doesn\'t have a default value\r\n### The error may exist in com/zzyl/nursing/mapper/ContractMapper.java (best guess)\r\n### The error may involve com.zzyl.nursing.mapper.ContractMapper.insert-Inline\r\n### The error occurred while setting parameters\r\n### SQL: INSERT INTO contract ( elder_id, contract_name, contract_number, agreement_path, third_party_phone, third_party_name, elder_name, start_date, end_date, status, sign_date, sort_order, create_by, create_time, remark ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )\r\n### Cause: java.sql.SQLException: Field \'update_by\' doesn\'t have a default value\n; Field \'update_by\' doesn\'t have a default value; nested exception is java.sql.SQLException: Field \'update_by\' doesn\'t have a default value', '2025-02-25 08:44:45', 38); +INSERT INTO `sys_oper_log` VALUES (553, '入住表', 1, 'com.zzyl.nursing.controller.CheckInController.apply()', 'POST', 1, 'admin', '院长办公室', '/nursing/checkIn/apply', '127.0.0.1', '内网IP', '{\"checkInConfigDto\":{\"bedFee\":6000.00,\"bedId\":55,\"code\":\"601\",\"deposit\":3000,\"endDate\":\"2025-03-27 00:00:00\",\"feeEndDate\":\"2025-03-26 00:00:00\",\"feeStartDate\":\"2025-02-26 00:00:00\",\"floorId\":6,\"floorName\":\"6楼\",\"governmentSubsidy\":6,\"insurancePayment\":5,\"nursingFee\":3200,\"nursingLevelId\":78,\"nursingLevelName\":\"3号护理等级\",\"otherFees\":4,\"roomId\":37,\"startDate\":\"2025-02-27 00:00:00\"},\"checkInContractDto\":{\"agreementPath\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/25/1c2111abe3b945f5b8d81158a4982769.pdf\",\"contractName\":\"光头强入住养老院合同\",\"signDate\":\"2025-02-26 00:00:00\",\"thirdPartyName\":\"熊大\",\"thirdPartyPhone\":\"13568560836\"},\"checkInElderDto\":{\"address\":\"狗熊岭\",\"age\":64,\"birthday\":\"1961-03-14\",\"idCardNationalEmblemImg\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/25/93077f4941ee4a73aab63812f963e24f.jpg\",\"idCardNo\":\"410231196103140736\",\"idCardPortraitImg\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/25/4f7e4776987b4502a07003eec01da4e8.jpg\",\"image\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/25/ac18ca5f769c404d99cab5b16981c75e.png\",\"name\":\"光头强\",\"phone\":\"15734907312\",\"sex\":1},\"elderFamilyDtoList\":[{\"kinship\":\"3\",\"name\":\"熊大\",\"phone\":\"13568560836\"},{\"kinship\":\"3\",\"name\":\"熊二\",\"phone\":\"15762073711\"}]}', NULL, 1, '\r\n### Error updating database. Cause: java.sql.SQLException: Field \'update_by\' doesn\'t have a default value\r\n### The error may exist in com/zzyl/nursing/mapper/ContractMapper.java (best guess)\r\n### The error may involve com.zzyl.nursing.mapper.ContractMapper.insert-Inline\r\n### The error occurred while setting parameters\r\n### SQL: INSERT INTO contract ( elder_id, contract_name, contract_number, agreement_path, third_party_phone, third_party_name, elder_name, start_date, end_date, status, sign_date, sort_order, create_by, create_time, remark ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )\r\n### Cause: java.sql.SQLException: Field \'update_by\' doesn\'t have a default value\n; Field \'update_by\' doesn\'t have a default value; nested exception is java.sql.SQLException: Field \'update_by\' doesn\'t have a default value', '2025-02-25 08:44:58', 49); +INSERT INTO `sys_oper_log` VALUES (554, '入住表', 1, 'com.zzyl.nursing.controller.CheckInController.apply()', 'POST', 1, 'admin', '院长办公室', '/nursing/checkIn/apply', '127.0.0.1', '内网IP', '{\"checkInConfigDto\":{\"bedFee\":6000.00,\"bedId\":55,\"code\":\"601\",\"deposit\":3000,\"endDate\":\"2025-03-27 00:00:00\",\"feeEndDate\":\"2025-03-26 00:00:00\",\"feeStartDate\":\"2025-02-26 00:00:00\",\"floorId\":6,\"floorName\":\"6楼\",\"governmentSubsidy\":6,\"insurancePayment\":5,\"nursingFee\":3200,\"nursingLevelId\":78,\"nursingLevelName\":\"3号护理等级\",\"otherFees\":4,\"roomId\":37,\"startDate\":\"2025-02-27 00:00:00\"},\"checkInContractDto\":{\"agreementPath\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/25/1c2111abe3b945f5b8d81158a4982769.pdf\",\"contractName\":\"光头强入住养老院合同\",\"signDate\":\"2025-02-26 00:00:00\",\"thirdPartyName\":\"熊大\",\"thirdPartyPhone\":\"13568560836\"},\"checkInElderDto\":{\"address\":\"狗熊岭\",\"age\":64,\"birthday\":\"1961-03-14\",\"idCardNationalEmblemImg\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/25/93077f4941ee4a73aab63812f963e24f.jpg\",\"idCardNo\":\"410231196103140736\",\"idCardPortraitImg\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/25/4f7e4776987b4502a07003eec01da4e8.jpg\",\"image\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/25/ac18ca5f769c404d99cab5b16981c75e.png\",\"name\":\"光头强\",\"phone\":\"15734907312\",\"sex\":1},\"elderFamilyDtoList\":[{\"kinship\":\"3\",\"name\":\"熊大\",\"phone\":\"13568560836\"},{\"kinship\":\"3\",\"name\":\"熊二\",\"phone\":\"15762073711\"}]}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-25 08:45:16', 73); +INSERT INTO `sys_oper_log` VALUES (555, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-25 08:45:22', 26); +INSERT INTO `sys_oper_log` VALUES (556, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-25 10:51:13', 110); +INSERT INTO `sys_oper_log` VALUES (557, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-25 10:58:32', 35); +INSERT INTO `sys_oper_log` VALUES (558, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-25 12:07:28', 81); +INSERT INTO `sys_oper_log` VALUES (559, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-25 12:09:03', 14); +INSERT INTO `sys_oper_log` VALUES (560, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-25 12:14:16', 110); +INSERT INTO `sys_oper_log` VALUES (561, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-25 12:15:50', 94); +INSERT INTO `sys_oper_log` VALUES (562, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-25 12:17:46', 13); +INSERT INTO `sys_oper_log` VALUES (563, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-25 12:18:11', 11); +INSERT INTO `sys_oper_log` VALUES (564, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-25 12:18:43', 7); +INSERT INTO `sys_oper_log` VALUES (565, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-25 12:28:38', 37); +INSERT INTO `sys_oper_log` VALUES (566, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-26 03:00:22', 109); +INSERT INTO `sys_oper_log` VALUES (567, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-26 03:01:25', 6); +INSERT INTO `sys_oper_log` VALUES (568, '入住表', 1, 'com.zzyl.nursing.controller.CheckInController.apply()', 'POST', 1, 'admin', '院长办公室', '/nursing/checkIn/apply', '127.0.0.1', '内网IP', '{\"checkInConfigDto\":{\"bedFee\":4000.00,\"bedId\":10,\"code\":\"107\",\"deposit\":3000,\"endDate\":\"2025-03-27 00:00:00\",\"feeEndDate\":\"2025-03-27 00:00:00\",\"feeStartDate\":\"2025-02-27 00:00:00\",\"floorId\":1,\"floorName\":\"1楼\",\"governmentSubsidy\":9,\"insurancePayment\":8,\"nursingFee\":2000,\"nursingLevelId\":77,\"nursingLevelName\":\"1号护理等级\",\"otherFees\":7,\"roomId\":7,\"startDate\":\"2025-02-27 00:00:00\"},\"checkInContractDto\":{\"agreementPath\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/26/bfd2c934e38f4e63bd528e28cd1c5dcc.pdf\",\"contractName\":\"华机菲养老院入住合同\",\"signDate\":\"2025-02-26 00:00:00\",\"thirdPartyName\":\"尤请涵\",\"thirdPartyPhone\":\"15209217512\"},\"checkInElderDto\":{\"address\":\"浙江省杭州市\",\"age\":68,\"birthday\":\"1958-09-22\",\"idCardNationalEmblemImg\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/26/bafa6edcae9b4604889ea5f41663cd00.jpg\",\"idCardNo\":\"210102195809225319\",\"idCardPortraitImg\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/26/9de0074ba1464b05a6aaa84c6b8334cb.jpg\",\"image\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/26/2aaca1c4b1cd45b8ab0defd08371ed14.png\",\"name\":\"华机菲\",\"phone\":\"13684810037\",\"sex\":0},\"elderFamilyDtoList\":[{\"kinship\":\"0\",\"name\":\"尤请涵\",\"phone\":\"15209217512\"},{\"kinship\":\"1\",\"name\":\"魏构为\",\"phone\":\"13786573590\"}]}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-26 03:04:20', 208); +INSERT INTO `sys_oper_log` VALUES (569, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-26 03:04:24', 11); +INSERT INTO `sys_oper_log` VALUES (570, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-26 03:04:38', 10); +INSERT INTO `sys_oper_log` VALUES (571, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-26 03:04:46', 9); +INSERT INTO `sys_oper_log` VALUES (572, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-26 03:04:49', 7); +INSERT INTO `sys_oper_log` VALUES (573, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-26 03:27:12', 14098); +INSERT INTO `sys_oper_log` VALUES (574, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-26 03:28:31', 18); +INSERT INTO `sys_oper_log` VALUES (575, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-26 03:29:48', 9); +INSERT INTO `sys_oper_log` VALUES (576, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-27 00:58:17', 166); +INSERT INTO `sys_oper_log` VALUES (577, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-27 00:59:09', 10); +INSERT INTO `sys_oper_log` VALUES (578, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-27 08:13:18', 108); +INSERT INTO `sys_oper_log` VALUES (579, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{\"@type\":\"java.util.HashMap\"},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{\"@type\":\"java.util.HashMap\"},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{\"@type\":\"java.util.HashMap\"},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-27 08:13:36', 9); +INSERT INTO `sys_oper_log` VALUES (580, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{\"@type\":\"java.util.HashMap\"},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{\"@type\":\"java.util.HashMap\"},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{\"@type\":\"java.util.HashMap\"},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-27 08:21:09', 61); +INSERT INTO `sys_oper_log` VALUES (581, '护理等级', 1, 'com.zzyl.nursing.controller.NursingLevelController.add()', 'POST', 1, 'admin', '院长办公室', '/nursing/level', '127.0.0.1', '内网IP', '{\"createBy\":\"1\",\"createTime\":\"2025-02-27 16:24:40\",\"description\":\"4号护理等级\",\"fee\":2300,\"id\":81,\"lplanId\":141,\"name\":\"4号护理等级\",\"params\":{},\"status\":1}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-27 08:24:39', 55); +INSERT INTO `sys_oper_log` VALUES (582, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"},{\"createBy\":\"1\",\"createTime\":\"2025-02-27 16:24:41\",\"description\":\"4号护理等级\",\"fee\":2300.00,\"id\":81,\"lplanId\":141,\"name\":\"4号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2025-02-27 08:24:39\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-27 08:25:01', 30); +INSERT INTO `sys_oper_log` VALUES (583, '定时任务', 1, 'com.zzyl.quartz.controller.SysJobController.add()', 'POST', 1, 'admin', '院长办公室', '/monitor/job', '127.0.0.1', '内网IP', '{\"concurrent\":\"1\",\"createBy\":\"admin\",\"cronExpression\":\"0/3 * * * * ?\",\"invokeTarget\":\"myJob.executeTask\",\"jobId\":100,\"jobName\":\"测试1\",\"misfirePolicy\":\"1\",\"nextValidTime\":\"2025-02-27 17:21:21\",\"params\":{},\"status\":\"1\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-27 09:21:19', 57); +INSERT INTO `sys_oper_log` VALUES (584, '定时任务', 2, 'com.zzyl.quartz.controller.SysJobController.run()', 'PUT', 1, 'admin', '院长办公室', '/monitor/job/run', '127.0.0.1', '内网IP', '{\"jobGroup\":\"DEFAULT\",\"jobId\":100,\"misfirePolicy\":\"0\",\"params\":{}}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-27 09:21:28', 17); +INSERT INTO `sys_oper_log` VALUES (585, '定时任务', 2, 'com.zzyl.quartz.controller.SysJobController.changeStatus()', 'PUT', 1, 'admin', '院长办公室', '/monitor/job/changeStatus', '127.0.0.1', '内网IP', '{\"jobId\":100,\"misfirePolicy\":\"0\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-27 09:21:34', 48); +INSERT INTO `sys_oper_log` VALUES (586, '定时任务', 2, 'com.zzyl.quartz.controller.SysJobController.changeStatus()', 'PUT', 1, 'admin', '院长办公室', '/monitor/job/changeStatus', '127.0.0.1', '内网IP', '{\"jobId\":100,\"misfirePolicy\":\"0\",\"params\":{},\"status\":\"1\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-27 09:21:48', 33); +INSERT INTO `sys_oper_log` VALUES (587, '定时任务', 2, 'com.zzyl.quartz.controller.SysJobController.edit()', 'PUT', 1, 'admin', '院长办公室', '/monitor/job', '127.0.0.1', '内网IP', '{\"concurrent\":\"1\",\"createBy\":\"admin\",\"createTime\":\"2025-02-27 09:21:19\",\"cronExpression\":\"0/3 * * * * ?\",\"invokeTarget\":\"myJob.executeTask\",\"jobGroup\":\"DEFAULT\",\"jobId\":100,\"jobName\":\"测试1\",\"misfirePolicy\":\"1\",\"nextValidTime\":\"2025-02-27 17:23:33\",\"params\":{},\"remark\":\"\",\"status\":\"1\",\"updateBy\":\"admin\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-27 09:23:30', 92); +INSERT INTO `sys_oper_log` VALUES (588, '定时任务', 2, 'com.zzyl.quartz.controller.SysJobController.changeStatus()', 'PUT', 1, 'admin', '院长办公室', '/monitor/job/changeStatus', '127.0.0.1', '内网IP', '{\"jobId\":100,\"misfirePolicy\":\"0\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-27 09:23:32', 29); +INSERT INTO `sys_oper_log` VALUES (589, '定时任务', 2, 'com.zzyl.quartz.controller.SysJobController.changeStatus()', 'PUT', 1, 'admin', '院长办公室', '/monitor/job/changeStatus', '127.0.0.1', '内网IP', '{\"jobId\":100,\"misfirePolicy\":\"0\",\"params\":{},\"status\":\"1\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-27 09:23:59', 36); +INSERT INTO `sys_oper_log` VALUES (590, '定时任务', 1, 'com.zzyl.quartz.controller.SysJobController.add()', 'POST', 1, 'admin', '院长办公室', '/monitor/job', '127.0.0.1', '内网IP', '{\"concurrent\":\"1\",\"createBy\":\"admin\",\"cronExpression\":\"0 1 0 * * ?\",\"invokeTarget\":\"contractJob.updateContractStatus\",\"jobGroup\":\"DEFAULT\",\"jobId\":101,\"jobName\":\"合同状态更新\",\"misfirePolicy\":\"1\",\"nextValidTime\":\"2025-02-28 00:01:00\",\"params\":{},\"status\":\"1\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-27 11:25:06', 38); +INSERT INTO `sys_oper_log` VALUES (591, '定时任务', 2, 'com.zzyl.quartz.controller.SysJobController.run()', 'PUT', 1, 'admin', '院长办公室', '/monitor/job/run', '127.0.0.1', '内网IP', '{\"jobGroup\":\"DEFAULT\",\"jobId\":101,\"misfirePolicy\":\"0\",\"params\":{}}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-27 11:25:14', 24); +INSERT INTO `sys_oper_log` VALUES (592, '定时任务', 2, 'com.zzyl.quartz.controller.SysJobController.run()', 'PUT', 1, 'admin', '院长办公室', '/monitor/job/run', '127.0.0.1', '内网IP', '{\"jobGroup\":\"DEFAULT\",\"jobId\":101,\"misfirePolicy\":\"0\",\"params\":{}}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-27 11:27:12', 13); +INSERT INTO `sys_oper_log` VALUES (593, '定时任务', 2, 'com.zzyl.quartz.controller.SysJobController.run()', 'PUT', 1, 'admin', '院长办公室', '/monitor/job/run', '127.0.0.1', '内网IP', '{\"jobGroup\":\"DEFAULT\",\"jobId\":101,\"misfirePolicy\":\"0\",\"params\":{}}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-27 11:28:26', 39); +INSERT INTO `sys_oper_log` VALUES (594, '定时任务', 2, 'com.zzyl.quartz.controller.SysJobController.run()', 'PUT', 1, 'admin', '院长办公室', '/monitor/job/run', '127.0.0.1', '内网IP', '{\"jobGroup\":\"DEFAULT\",\"jobId\":101,\"misfirePolicy\":\"0\",\"params\":{}}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-27 11:29:16', 11); +INSERT INTO `sys_oper_log` VALUES (595, '定时任务', 2, 'com.zzyl.quartz.controller.SysJobController.run()', 'PUT', 1, 'admin', '院长办公室', '/monitor/job/run', '127.0.0.1', '内网IP', '{\"jobGroup\":\"DEFAULT\",\"jobId\":101,\"misfirePolicy\":\"0\",\"params\":{}}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-27 11:29:46', 5080); +INSERT INTO `sys_oper_log` VALUES (596, '定时任务', 2, 'com.zzyl.quartz.controller.SysJobController.run()', 'PUT', 1, 'admin', '院长办公室', '/monitor/job/run', '127.0.0.1', '内网IP', '{\"jobGroup\":\"DEFAULT\",\"jobId\":101,\"misfirePolicy\":\"0\",\"params\":{}}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-27 11:32:33', 45); +INSERT INTO `sys_oper_log` VALUES (597, '定时任务', 2, 'com.zzyl.quartz.controller.SysJobController.run()', 'PUT', 1, 'admin', '院长办公室', '/monitor/job/run', '127.0.0.1', '内网IP', '{\"jobGroup\":\"DEFAULT\",\"jobId\":101,\"misfirePolicy\":\"0\",\"params\":{}}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-27 11:33:54', 41); +INSERT INTO `sys_oper_log` VALUES (598, '定时任务', 2, 'com.zzyl.quartz.controller.SysJobController.run()', 'PUT', 1, 'admin', '院长办公室', '/monitor/job/run', '127.0.0.1', '内网IP', '{\"jobGroup\":\"DEFAULT\",\"jobId\":101,\"misfirePolicy\":\"0\",\"params\":{}}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-27 11:34:14', 11); +INSERT INTO `sys_oper_log` VALUES (599, '定时任务', 2, 'com.zzyl.quartz.controller.SysJobController.run()', 'PUT', 1, 'admin', '院长办公室', '/monitor/job/run', '127.0.0.1', '内网IP', '{\"jobGroup\":\"DEFAULT\",\"jobId\":101,\"misfirePolicy\":\"0\",\"params\":{}}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-27 11:36:10', 47); +INSERT INTO `sys_oper_log` VALUES (600, '定时任务', 2, 'com.zzyl.quartz.controller.SysJobController.run()', 'PUT', 1, 'admin', '院长办公室', '/monitor/job/run', '127.0.0.1', '内网IP', '{\"jobGroup\":\"DEFAULT\",\"jobId\":101,\"misfirePolicy\":\"0\",\"params\":{}}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-27 11:40:20', 51); +INSERT INTO `sys_oper_log` VALUES (601, '定时任务', 2, 'com.zzyl.quartz.controller.SysJobController.run()', 'PUT', 1, 'admin', '院长办公室', '/monitor/job/run', '127.0.0.1', '内网IP', '{\"jobGroup\":\"DEFAULT\",\"jobId\":101,\"misfirePolicy\":\"0\",\"params\":{}}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-27 11:42:16', 39); +INSERT INTO `sys_oper_log` VALUES (602, '定时任务', 2, 'com.zzyl.quartz.controller.SysJobController.run()', 'PUT', 1, 'admin', '院长办公室', '/monitor/job/run', '127.0.0.1', '内网IP', '{\"jobGroup\":\"DEFAULT\",\"jobId\":101,\"misfirePolicy\":\"0\",\"params\":{}}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-27 11:43:04', 4777); +INSERT INTO `sys_oper_log` VALUES (603, '定时任务', 2, 'com.zzyl.quartz.controller.SysJobController.run()', 'PUT', 1, 'admin', '院长办公室', '/monitor/job/run', '127.0.0.1', '内网IP', '{\"jobGroup\":\"DEFAULT\",\"jobId\":101,\"misfirePolicy\":\"0\",\"params\":{}}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-27 11:44:40', 9); +INSERT INTO `sys_oper_log` VALUES (604, '定时任务', 2, 'com.zzyl.quartz.controller.SysJobController.changeStatus()', 'PUT', 1, 'admin', '院长办公室', '/monitor/job/changeStatus', '127.0.0.1', '内网IP', '{\"jobId\":101,\"misfirePolicy\":\"0\",\"params\":{},\"status\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-27 11:49:37', 34); +INSERT INTO `sys_oper_log` VALUES (605, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"},{\"createBy\":\"1\",\"createTime\":\"2025-02-27 16:24:41\",\"description\":\"4号护理等级\",\"fee\":2300.00,\"id\":81,\"lplanId\":141,\"name\":\"4号护理等级\",\"params\":{},\"status\":1,\"updateTime\":\"2025-02-27 08:24:39\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-27 12:19:07', 55); +INSERT INTO `sys_oper_log` VALUES (606, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{\"@type\":\"java.util.HashMap\"},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{\"@type\":\"java.util.HashMap\"},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{\"@type\":\"java.util.HashMap\"},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"},{\"createBy\":\"1\",\"createTime\":\"2025-02-27 16:24:41\",\"description\":\"4号护理等级\",\"fee\":2300.00,\"id\":81,\"lplanId\":141,\"name\":\"4号护理等级\",\"params\":{\"@type\":\"java.util.HashMap\"},\"status\":1,\"updateTime\":\"2025-02-27 08:24:39\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-27 12:19:21', 7); +INSERT INTO `sys_oper_log` VALUES (607, '护理项目', 2, 'com.zzyl.nursing.controller.NursingProjectController.edit()', 'PUT', 1, 'admin', '院长办公室', '/nursing/project', '127.0.0.1', '内网IP', '{\"createBy\":\"1\",\"createTime\":\"2024-08-29 16:55:37\",\"id\":9,\"image\":\"https://itheim.oss-cn-beijing.aliyuncs.com/dc004cc2-688c-4d22-8fbc-8e923219a2bd.png\",\"name\":\"心理咨询\",\"nursingRequirement\":\"无\",\"orderNo\":1,\"params\":{},\"price\":70,\"status\":1,\"unit\":\"小时\",\"updateBy\":\"1\",\"updateTime\":\"2025-02-27 20:23:58\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-27 12:23:57', 26); +INSERT INTO `sys_oper_log` VALUES (608, '护理计划', 2, 'com.zzyl.nursing.controller.NursingPlanController.edit()', 'PUT', 1, 'admin', '院长办公室', '/nursing/plan', '127.0.0.1', '内网IP', '{\"id\":141,\"planName\":\"4号护理计划\",\"projectPlans\":[{\"executeCycle\":1,\"executeFrequency\":2,\"executeTime\":\"13:50:33\",\"id\":1754,\"params\":{},\"planId\":141,\"projectId\":5},{\"executeCycle\":0,\"executeFrequency\":1,\"executeTime\":\"18:16:22\",\"id\":1756,\"params\":{},\"planId\":141,\"projectId\":2}],\"sortNo\":1,\"status\":1}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-27 12:24:21', 73); +INSERT INTO `sys_oper_log` VALUES (609, '菜单管理', 2, 'com.zzyl.web.controller.system.SysMenuController.edit()', 'PUT', 1, 'admin', '院长办公室', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"createTime\":\"2024-11-09 01:19:22\",\"icon\":\"message\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2049,\"menuName\":\"测试菜单\",\"menuType\":\"M\",\"orderNum\":10,\"params\":{},\"parentId\":0,\"path\":\"test\",\"perms\":\"\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"1\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-28 01:17:06', 73); +INSERT INTO `sys_oper_log` VALUES (610, '菜单管理', 2, 'com.zzyl.web.controller.system.SysMenuController.edit()', 'PUT', 1, 'admin', '院长办公室', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"createTime\":\"2024-11-09 01:19:22\",\"icon\":\"message\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2049,\"menuName\":\"测试菜单\",\"menuType\":\"M\",\"orderNum\":10,\"params\":{},\"parentId\":0,\"path\":\"test\",\"perms\":\"\",\"routeName\":\"\",\"status\":\"0\",\"updateBy\":\"admin\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-28 01:17:22', 21); +INSERT INTO `sys_oper_log` VALUES (611, '菜单管理', 2, 'com.zzyl.web.controller.system.SysMenuController.edit()', 'PUT', 1, 'admin', '院长办公室', '/system/menu', '127.0.0.1', '内网IP', '{\"children\":[],\"createTime\":\"2024-11-09 01:19:22\",\"icon\":\"message\",\"isCache\":\"0\",\"isFrame\":\"1\",\"menuId\":2049,\"menuName\":\"测试菜单\",\"menuType\":\"M\",\"orderNum\":10,\"params\":{},\"parentId\":0,\"path\":\"test\",\"perms\":\"\",\"routeName\":\"\",\"status\":\"1\",\"updateBy\":\"admin\",\"visible\":\"0\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-28 01:17:31', 29); +INSERT INTO `sys_oper_log` VALUES (612, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{\"@type\":\"java.util.HashMap\"},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{\"@type\":\"java.util.HashMap\"},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{\"@type\":\"java.util.HashMap\"},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"},{\"createBy\":\"1\",\"createTime\":\"2025-02-27 16:24:41\",\"description\":\"4号护理等级\",\"fee\":2300.00,\"id\":81,\"lplanId\":141,\"name\":\"4号护理等级\",\"params\":{\"@type\":\"java.util.HashMap\"},\"status\":1,\"updateTime\":\"2025-02-27 08:24:39\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-28 01:20:08', 59); +INSERT INTO `sys_oper_log` VALUES (613, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{\"@type\":\"java.util.HashMap\"},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{\"@type\":\"java.util.HashMap\"},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{\"@type\":\"java.util.HashMap\"},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"},{\"createBy\":\"1\",\"createTime\":\"2025-02-27 16:24:41\",\"description\":\"4号护理等级\",\"fee\":2300.00,\"id\":81,\"lplanId\":141,\"name\":\"4号护理等级\",\"params\":{\"@type\":\"java.util.HashMap\"},\"status\":1,\"updateTime\":\"2025-02-27 08:24:39\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-28 01:23:49', 4); +INSERT INTO `sys_oper_log` VALUES (614, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{\"@type\":\"java.util.HashMap\"},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{\"@type\":\"java.util.HashMap\"},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{\"@type\":\"java.util.HashMap\"},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"},{\"createBy\":\"1\",\"createTime\":\"2025-02-27 16:24:41\",\"description\":\"4号护理等级\",\"fee\":2300.00,\"id\":81,\"lplanId\":141,\"name\":\"4号护理等级\",\"params\":{\"@type\":\"java.util.HashMap\"},\"status\":1,\"updateTime\":\"2025-02-27 08:24:39\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-28 01:30:10', 6); +INSERT INTO `sys_oper_log` VALUES (615, '护理等级', 3, 'com.zzyl.nursing.controller.NursingLevelController.getByEnableLevel()', 'GET', 1, 'admin', '院长办公室', '/nursing/level/all', '127.0.0.1', '内网IP', '{}', '{\"code\":200,\"data\":[{\"createTime\":\"2024-08-14 16:33:16\",\"description\":\"1223\",\"fee\":1500.00,\"id\":76,\"lplanId\":134,\"name\":\"2号护理等级\",\"params\":{\"@type\":\"java.util.HashMap\"},\"status\":1,\"updateTime\":\"2024-08-29 16:57:23\"},{\"createTime\":\"2024-08-20 11:18:21\",\"description\":\"1223\",\"fee\":2000.00,\"id\":77,\"lplanId\":133,\"name\":\"1号护理等级\",\"params\":{\"@type\":\"java.util.HashMap\"},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:42:34\"},{\"createTime\":\"2024-08-29 16:58:00\",\"description\":\"无\",\"fee\":3200.00,\"id\":78,\"lplanId\":135,\"name\":\"3号护理等级\",\"params\":{\"@type\":\"java.util.HashMap\"},\"status\":1,\"updateBy\":\"1\",\"updateTime\":\"2025-02-25 09:28:51\"},{\"createBy\":\"1\",\"createTime\":\"2025-02-27 16:24:41\",\"description\":\"4号护理等级\",\"fee\":2300.00,\"id\":81,\"lplanId\":141,\"name\":\"4号护理等级\",\"params\":{\"@type\":\"java.util.HashMap\"},\"status\":1,\"updateTime\":\"2025-02-27 08:24:39\"}],\"msg\":\"操作成功\"}', 0, NULL, '2025-02-28 01:30:29', 3); +INSERT INTO `sys_oper_log` VALUES (616, '代码生成', 6, 'com.zzyl.generator.controller.GenController.importTableSave()', 'POST', 1, 'admin', '院长办公室', '/tool/gen/importTable', '127.0.0.1', '内网IP', '{\"tables\":\"health_assessment\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-28 03:38:26', 222); +INSERT INTO `sys_oper_log` VALUES (617, '代码生成', 2, 'com.zzyl.generator.controller.GenController.editSave()', 'PUT', 1, 'admin', '院长办公室', '/tool/gen', '127.0.0.1', '内网IP', '{\"businessName\":\"assessment\",\"className\":\"HealthAssessment\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键\",\"columnId\":345,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2025-02-28 03:38:26\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":23,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"ElderName\",\"columnComment\":\"老人姓名\",\"columnId\":346,\"columnName\":\"elder_name\",\"columnType\":\"varchar(255)\",\"createBy\":\"admin\",\"createTime\":\"2025-02-28 03:38:26\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"elderName\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":false,\"sort\":2,\"superColumn\":false,\"tableId\":23,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"IdCard\",\"columnComment\":\"身份证号\",\"columnId\":347,\"columnName\":\"id_card\",\"columnType\":\"varchar(255)\",\"createBy\":\"admin\",\"createTime\":\"2025-02-28 03:38:26\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"idCard\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":false,\"sort\":3,\"superColumn\":false,\"tableId\":23,\"updateBy\":\"\",\"usableColumn\":false},{\"capJavaField\":\"BirthDate\",\"columnComment\":\"出生日期\",\"columnId\":348,\"columnName\":\"birth_date\",\"columnType\":\"datetime\",\"createBy\":\"admin\",\"createTime\":\"2025-02-28 03:38:26\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"datetime\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRe', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-28 03:39:51', 192); +INSERT INTO `sys_oper_log` VALUES (618, '代码生成', 2, 'com.zzyl.generator.controller.GenController.editSave()', 'PUT', 1, 'admin', '院长办公室', '/tool/gen', '127.0.0.1', '内网IP', '{\"businessName\":\"healthAssessment\",\"className\":\"HealthAssessment\",\"columns\":[{\"capJavaField\":\"Id\",\"columnComment\":\"主键\",\"columnId\":345,\"columnName\":\"id\",\"columnType\":\"bigint\",\"createBy\":\"admin\",\"createTime\":\"2025-02-28 03:38:26\",\"dictType\":\"\",\"edit\":false,\"htmlType\":\"input\",\"increment\":true,\"insert\":true,\"isIncrement\":\"1\",\"isInsert\":\"1\",\"isPk\":\"1\",\"isRequired\":\"0\",\"javaField\":\"id\",\"javaType\":\"Long\",\"list\":false,\"params\":{},\"pk\":true,\"query\":false,\"queryType\":\"EQ\",\"required\":false,\"sort\":1,\"superColumn\":false,\"tableId\":23,\"updateBy\":\"\",\"updateTime\":\"2025-02-28 03:39:50\",\"usableColumn\":false},{\"capJavaField\":\"ElderName\",\"columnComment\":\"老人姓名\",\"columnId\":346,\"columnName\":\"elder_name\",\"columnType\":\"varchar(255)\",\"createBy\":\"admin\",\"createTime\":\"2025-02-28 03:38:26\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"elderName\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"LIKE\",\"required\":false,\"sort\":2,\"superColumn\":false,\"tableId\":23,\"updateBy\":\"\",\"updateTime\":\"2025-02-28 03:39:50\",\"usableColumn\":false},{\"capJavaField\":\"IdCard\",\"columnComment\":\"身份证号\",\"columnId\":347,\"columnName\":\"id_card\",\"columnType\":\"varchar(255)\",\"createBy\":\"admin\",\"createTime\":\"2025-02-28 03:38:26\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"input\",\"increment\":false,\"insert\":true,\"isEdit\":\"1\",\"isIncrement\":\"0\",\"isInsert\":\"1\",\"isList\":\"1\",\"isPk\":\"0\",\"isQuery\":\"1\",\"isRequired\":\"0\",\"javaField\":\"idCard\",\"javaType\":\"String\",\"list\":true,\"params\":{},\"pk\":false,\"query\":true,\"queryType\":\"EQ\",\"required\":false,\"sort\":3,\"superColumn\":false,\"tableId\":23,\"updateBy\":\"\",\"updateTime\":\"2025-02-28 03:39:50\",\"usableColumn\":false},{\"capJavaField\":\"BirthDate\",\"columnComment\":\"出生日期\",\"columnId\":348,\"columnName\":\"birth_date\",\"columnType\":\"datetime\",\"createBy\":\"admin\",\"createTime\":\"2025-02-28 03:38:26\",\"dictType\":\"\",\"edit\":true,\"htmlType\":\"datetime\",\"increment', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-02-28 07:01:08', 297); +INSERT INTO `sys_oper_log` VALUES (619, '代码生成', 8, 'com.zzyl.generator.controller.GenController.batchGenCode()', 'GET', 1, 'admin', '院长办公室', '/tool/gen/batchGenCode', '127.0.0.1', '内网IP', '{\"tables\":\"health_assessment\"}', NULL, 0, NULL, '2025-02-28 07:01:10', 400); +INSERT INTO `sys_oper_log` VALUES (620, '健康评估', 1, 'com.zzyl.nursing.controller.HealthAssessmentController.add()', 'POST', 1, 'admin', '院长办公室', '/nursing/healthAssessment', '127.0.0.1', '内网IP', '{\"elderName\":\"张芳\",\"idCard\":\"410182195309190744\",\"physicalExamInstitution\":\"传智健康体检中心\",\"physicalReportUrl\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/28/5c69c47653e249f3a35e2bebbbdae897.pdf\"}', '{\"msg\":\"操作成功\",\"code\":200,\"data\":1}', 0, NULL, '2025-02-28 10:23:09', 97754); +INSERT INTO `sys_oper_log` VALUES (621, '健康评估', 1, 'com.zzyl.nursing.controller.HealthAssessmentController.add()', 'POST', 1, 'admin', '院长办公室', '/nursing/healthAssessment', '127.0.0.1', '内网IP', '{\"elderName\":\"张芳\",\"idCard\":\"410182195309190744\",\"physicalExamInstitution\":\"传智健康体检中心\",\"physicalReportUrl\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/28/4c0f63cc991b43d1b8839f2500749c9b.pdf\"}', '{\"msg\":\"操作成功\",\"code\":200,\"data\":1}', 0, NULL, '2025-02-28 10:29:29', 95528); +INSERT INTO `sys_oper_log` VALUES (622, '健康评估', 1, 'com.zzyl.nursing.controller.HealthAssessmentController.add()', 'POST', 1, 'admin', '院长办公室', '/nursing/healthAssessment', '127.0.0.1', '内网IP', '{\"elderName\":\"张芳\",\"idCard\":\"410182195309190744\",\"physicalExamInstitution\":\"传智健康体检中心\",\"physicalReportUrl\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/28/0d96b6a7923449e88ee7a5d41ac24d47.pdf\"}', '{\"msg\":\"操作成功\",\"code\":200,\"data\":1}', 0, NULL, '2025-02-28 10:56:04', 144680); +INSERT INTO `sys_oper_log` VALUES (623, '健康评估', 1, 'com.zzyl.nursing.controller.HealthAssessmentController.add()', 'POST', 1, 'admin', '院长办公室', '/nursing/healthAssessment', '127.0.0.1', '内网IP', '{\"elderName\":\"张芳\",\"idCard\":\"410182195309190744\",\"physicalExamInstitution\":\"传智\",\"physicalReportUrl\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/28/f055b9e5b3aa444691535107fa3d3fa5.pdf\"}', '{\"msg\":\"操作成功\",\"code\":200,\"data\":1}', 0, NULL, '2025-02-28 11:02:52', 109348); +INSERT INTO `sys_oper_log` VALUES (624, '健康评估', 1, 'com.zzyl.nursing.controller.HealthAssessmentController.add()', 'POST', 1, 'admin', '院长办公室', '/nursing/healthAssessment', '127.0.0.1', '内网IP', '{\"elderName\":\"张芳\",\"idCard\":\"410182195309190744\",\"physicalExamInstitution\":\"传智健康体检中心\",\"physicalReportUrl\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/28/b2971c0597a44d2c9386e7406557b483.pdf\"}', '{\"msg\":\"操作成功\",\"code\":200,\"data\":1}', 0, NULL, '2025-02-28 11:09:09', 104256); +INSERT INTO `sys_oper_log` VALUES (625, '健康评估', 1, 'com.zzyl.nursing.controller.HealthAssessmentController.add()', 'POST', 1, 'admin', '院长办公室', '/nursing/healthAssessment', '127.0.0.1', '内网IP', '{\"elderName\":\"张芳\",\"idCard\":\"410182195309190744\",\"physicalExamInstitution\":\"传智健康体检中心\",\"physicalReportUrl\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/28/b97984964ec34ac3acf51f5b1c877948.pdf\"}', '{\"msg\":\"操作成功\",\"code\":200,\"data\":4}', 0, NULL, '2025-02-28 11:13:34', 128005); +INSERT INTO `sys_oper_log` VALUES (626, '健康评估', 1, 'com.zzyl.nursing.controller.HealthAssessmentController.add()', 'POST', 1, 'admin', '院长办公室', '/nursing/healthAssessment', '127.0.0.1', '内网IP', '{\"elderName\":\"张芳\",\"idCard\":\"410182195309190744\",\"physicalExamInstitution\":\"传智健康体检中心\",\"physicalReportUrl\":\"https://hzhm-mlgb2.oss-cn-beijing.aliyuncs.com/2025/02/28/0b3d9d0e75c24c7f8f80585a00f89988.pdf\"}', '{\"msg\":\"操作成功\",\"code\":200,\"data\":5}', 0, NULL, '2025-02-28 11:16:54', 117049); + +-- ---------------------------- +-- Table structure for sys_post +-- ---------------------------- +DROP TABLE IF EXISTS `sys_post`; +CREATE TABLE `sys_post` ( + `post_id` bigint NOT NULL AUTO_INCREMENT COMMENT '岗位ID', + `post_code` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '岗位编码', + `post_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '岗位名称', + `post_sort` int NOT NULL COMMENT '显示顺序', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '状态(0正常 1停用)', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`post_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '岗位信息表' ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of sys_post +-- ---------------------------- +INSERT INTO `sys_post` VALUES (1, 'ceo', '董事长', 1, '0', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_post` VALUES (2, 'se', '项目经理', 2, '0', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_post` VALUES (3, 'hr', '人力资源', 3, '0', 'admin', '2024-08-14 02:48:23', '', NULL, ''); +INSERT INTO `sys_post` VALUES (4, 'user', '普通员工', 4, '0', 'admin', '2024-08-14 02:48:23', '', NULL, ''); + +-- ---------------------------- +-- Table structure for sys_role +-- ---------------------------- +DROP TABLE IF EXISTS `sys_role`; +CREATE TABLE `sys_role` ( + `role_id` bigint NOT NULL AUTO_INCREMENT COMMENT '角色ID', + `role_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '角色名称', + `role_key` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '角色权限字符串', + `role_sort` int NOT NULL COMMENT '显示顺序', + `data_scope` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '1' COMMENT '数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限)', + `menu_check_strictly` tinyint(1) NULL DEFAULT 1 COMMENT '菜单树选择项是否关联显示', + `dept_check_strictly` tinyint(1) NULL DEFAULT 1 COMMENT '部门树选择项是否关联显示', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '角色状态(0正常 1停用)', + `del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`role_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 104 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '角色信息表' ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of sys_role +-- ---------------------------- +INSERT INTO `sys_role` VALUES (1, '超级管理员', 'admin', 1, '1', 1, 1, '0', '0', 'admin', '2024-08-14 02:48:23', '', NULL, '超级管理员'); +INSERT INTO `sys_role` VALUES (2, '普通角色', 'common', 2, '2', 1, 1, '0', '0', 'admin', '2024-08-14 02:48:23', 'admin', '2024-10-18 10:38:36', '普通角色'); +INSERT INTO `sys_role` VALUES (100, '护理员', 'nursingUser', 3, '1', 1, 1, '0', '0', 'admin', '2024-09-24 17:25:26', 'admin', '2024-10-18 10:38:20', NULL); +INSERT INTO `sys_role` VALUES (101, '维修工', 'maintainer', 4, '1', 1, 1, '0', '0', 'admin', '2024-09-24 17:26:31', 'admin', '2024-10-18 10:38:13', NULL); +INSERT INTO `sys_role` VALUES (102, '客服专员', 'customerService', 5, '1', 1, 1, '0', '0', 'admin', '2024-09-24 17:27:42', 'admin', '2024-10-18 10:38:05', NULL); +INSERT INTO `sys_role` VALUES (103, '院长', 'SuperAdministrator', 6, '1', 1, 1, '0', '0', 'admin', '2024-09-24 17:30:54', 'admin', '2024-10-18 10:37:55', NULL); + +-- ---------------------------- +-- Table structure for sys_role_dept +-- ---------------------------- +DROP TABLE IF EXISTS `sys_role_dept`; +CREATE TABLE `sys_role_dept` ( + `role_id` bigint NOT NULL COMMENT '角色ID', + `dept_id` bigint NOT NULL COMMENT '部门ID', + PRIMARY KEY (`role_id`, `dept_id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '角色和部门关联表' ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of sys_role_dept +-- ---------------------------- +INSERT INTO `sys_role_dept` VALUES (2, 100); +INSERT INTO `sys_role_dept` VALUES (2, 101); +INSERT INTO `sys_role_dept` VALUES (2, 105); + +-- ---------------------------- +-- Table structure for sys_role_menu +-- ---------------------------- +DROP TABLE IF EXISTS `sys_role_menu`; +CREATE TABLE `sys_role_menu` ( + `role_id` bigint NOT NULL COMMENT '角色ID', + `menu_id` bigint NOT NULL COMMENT '菜单ID', + PRIMARY KEY (`role_id`, `menu_id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '角色和菜单关联表' ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of sys_role_menu +-- ---------------------------- +INSERT INTO `sys_role_menu` VALUES (2, 1); +INSERT INTO `sys_role_menu` VALUES (2, 2); +INSERT INTO `sys_role_menu` VALUES (2, 3); +INSERT INTO `sys_role_menu` VALUES (2, 100); +INSERT INTO `sys_role_menu` VALUES (2, 101); +INSERT INTO `sys_role_menu` VALUES (2, 102); +INSERT INTO `sys_role_menu` VALUES (2, 103); +INSERT INTO `sys_role_menu` VALUES (2, 104); +INSERT INTO `sys_role_menu` VALUES (2, 105); +INSERT INTO `sys_role_menu` VALUES (2, 106); +INSERT INTO `sys_role_menu` VALUES (2, 107); +INSERT INTO `sys_role_menu` VALUES (2, 108); +INSERT INTO `sys_role_menu` VALUES (2, 109); +INSERT INTO `sys_role_menu` VALUES (2, 110); +INSERT INTO `sys_role_menu` VALUES (2, 111); +INSERT INTO `sys_role_menu` VALUES (2, 112); +INSERT INTO `sys_role_menu` VALUES (2, 113); +INSERT INTO `sys_role_menu` VALUES (2, 114); +INSERT INTO `sys_role_menu` VALUES (2, 115); +INSERT INTO `sys_role_menu` VALUES (2, 116); +INSERT INTO `sys_role_menu` VALUES (2, 117); +INSERT INTO `sys_role_menu` VALUES (2, 500); +INSERT INTO `sys_role_menu` VALUES (2, 501); +INSERT INTO `sys_role_menu` VALUES (2, 1000); +INSERT INTO `sys_role_menu` VALUES (2, 1001); +INSERT INTO `sys_role_menu` VALUES (2, 1002); +INSERT INTO `sys_role_menu` VALUES (2, 1003); +INSERT INTO `sys_role_menu` VALUES (2, 1004); +INSERT INTO `sys_role_menu` VALUES (2, 1005); +INSERT INTO `sys_role_menu` VALUES (2, 1006); +INSERT INTO `sys_role_menu` VALUES (2, 1007); +INSERT INTO `sys_role_menu` VALUES (2, 1008); +INSERT INTO `sys_role_menu` VALUES (2, 1009); +INSERT INTO `sys_role_menu` VALUES (2, 1010); +INSERT INTO `sys_role_menu` VALUES (2, 1011); +INSERT INTO `sys_role_menu` VALUES (2, 1012); +INSERT INTO `sys_role_menu` VALUES (2, 1013); +INSERT INTO `sys_role_menu` VALUES (2, 1014); +INSERT INTO `sys_role_menu` VALUES (2, 1015); +INSERT INTO `sys_role_menu` VALUES (2, 1016); +INSERT INTO `sys_role_menu` VALUES (2, 1017); +INSERT INTO `sys_role_menu` VALUES (2, 1018); +INSERT INTO `sys_role_menu` VALUES (2, 1019); +INSERT INTO `sys_role_menu` VALUES (2, 1020); +INSERT INTO `sys_role_menu` VALUES (2, 1021); +INSERT INTO `sys_role_menu` VALUES (2, 1022); +INSERT INTO `sys_role_menu` VALUES (2, 1023); +INSERT INTO `sys_role_menu` VALUES (2, 1024); +INSERT INTO `sys_role_menu` VALUES (2, 1025); +INSERT INTO `sys_role_menu` VALUES (2, 1026); +INSERT INTO `sys_role_menu` VALUES (2, 1027); +INSERT INTO `sys_role_menu` VALUES (2, 1028); +INSERT INTO `sys_role_menu` VALUES (2, 1029); +INSERT INTO `sys_role_menu` VALUES (2, 1030); +INSERT INTO `sys_role_menu` VALUES (2, 1031); +INSERT INTO `sys_role_menu` VALUES (2, 1032); +INSERT INTO `sys_role_menu` VALUES (2, 1033); +INSERT INTO `sys_role_menu` VALUES (2, 1034); +INSERT INTO `sys_role_menu` VALUES (2, 1035); +INSERT INTO `sys_role_menu` VALUES (2, 1036); +INSERT INTO `sys_role_menu` VALUES (2, 1037); +INSERT INTO `sys_role_menu` VALUES (2, 1038); +INSERT INTO `sys_role_menu` VALUES (2, 1039); +INSERT INTO `sys_role_menu` VALUES (2, 1040); +INSERT INTO `sys_role_menu` VALUES (2, 1041); +INSERT INTO `sys_role_menu` VALUES (2, 1042); +INSERT INTO `sys_role_menu` VALUES (2, 1043); +INSERT INTO `sys_role_menu` VALUES (2, 1044); +INSERT INTO `sys_role_menu` VALUES (2, 1045); +INSERT INTO `sys_role_menu` VALUES (2, 1046); +INSERT INTO `sys_role_menu` VALUES (2, 1047); +INSERT INTO `sys_role_menu` VALUES (2, 1048); +INSERT INTO `sys_role_menu` VALUES (2, 1049); +INSERT INTO `sys_role_menu` VALUES (2, 1050); +INSERT INTO `sys_role_menu` VALUES (2, 1051); +INSERT INTO `sys_role_menu` VALUES (2, 1052); +INSERT INTO `sys_role_menu` VALUES (2, 1053); +INSERT INTO `sys_role_menu` VALUES (2, 1054); +INSERT INTO `sys_role_menu` VALUES (2, 1055); +INSERT INTO `sys_role_menu` VALUES (2, 1056); +INSERT INTO `sys_role_menu` VALUES (2, 1057); +INSERT INTO `sys_role_menu` VALUES (2, 1058); +INSERT INTO `sys_role_menu` VALUES (2, 1059); +INSERT INTO `sys_role_menu` VALUES (2, 1060); +INSERT INTO `sys_role_menu` VALUES (2, 2000); +INSERT INTO `sys_role_menu` VALUES (2, 2001); +INSERT INTO `sys_role_menu` VALUES (2, 2002); +INSERT INTO `sys_role_menu` VALUES (2, 2003); +INSERT INTO `sys_role_menu` VALUES (2, 2004); +INSERT INTO `sys_role_menu` VALUES (2, 2005); +INSERT INTO `sys_role_menu` VALUES (2, 2006); +INSERT INTO `sys_role_menu` VALUES (2, 2007); +INSERT INTO `sys_role_menu` VALUES (2, 2008); +INSERT INTO `sys_role_menu` VALUES (2, 2009); +INSERT INTO `sys_role_menu` VALUES (2, 2010); +INSERT INTO `sys_role_menu` VALUES (2, 2011); +INSERT INTO `sys_role_menu` VALUES (2, 2012); +INSERT INTO `sys_role_menu` VALUES (2, 2013); +INSERT INTO `sys_role_menu` VALUES (2, 2014); +INSERT INTO `sys_role_menu` VALUES (2, 2015); +INSERT INTO `sys_role_menu` VALUES (2, 2016); +INSERT INTO `sys_role_menu` VALUES (2, 2017); +INSERT INTO `sys_role_menu` VALUES (2, 2018); +INSERT INTO `sys_role_menu` VALUES (2, 2019); +INSERT INTO `sys_role_menu` VALUES (2, 2020); +INSERT INTO `sys_role_menu` VALUES (2, 2021); +INSERT INTO `sys_role_menu` VALUES (2, 2022); +INSERT INTO `sys_role_menu` VALUES (2, 2023); +INSERT INTO `sys_role_menu` VALUES (2, 2024); +INSERT INTO `sys_role_menu` VALUES (2, 2025); +INSERT INTO `sys_role_menu` VALUES (2, 2026); +INSERT INTO `sys_role_menu` VALUES (2, 2027); +INSERT INTO `sys_role_menu` VALUES (2, 2028); +INSERT INTO `sys_role_menu` VALUES (2, 2035); +INSERT INTO `sys_role_menu` VALUES (2, 2036); +INSERT INTO `sys_role_menu` VALUES (2, 2037); +INSERT INTO `sys_role_menu` VALUES (2, 2038); +INSERT INTO `sys_role_menu` VALUES (2, 2039); +INSERT INTO `sys_role_menu` VALUES (2, 2040); +INSERT INTO `sys_role_menu` VALUES (2, 2041); +INSERT INTO `sys_role_menu` VALUES (2, 2042); +INSERT INTO `sys_role_menu` VALUES (2, 2043); +INSERT INTO `sys_role_menu` VALUES (2, 2044); +INSERT INTO `sys_role_menu` VALUES (2, 2045); +INSERT INTO `sys_role_menu` VALUES (2, 2046); +INSERT INTO `sys_role_menu` VALUES (2, 2047); +INSERT INTO `sys_role_menu` VALUES (2, 2048); +INSERT INTO `sys_role_menu` VALUES (2, 2054); +INSERT INTO `sys_role_menu` VALUES (100, 1); +INSERT INTO `sys_role_menu` VALUES (100, 2); +INSERT INTO `sys_role_menu` VALUES (100, 3); +INSERT INTO `sys_role_menu` VALUES (100, 100); +INSERT INTO `sys_role_menu` VALUES (100, 101); +INSERT INTO `sys_role_menu` VALUES (100, 102); +INSERT INTO `sys_role_menu` VALUES (100, 103); +INSERT INTO `sys_role_menu` VALUES (100, 104); +INSERT INTO `sys_role_menu` VALUES (100, 105); +INSERT INTO `sys_role_menu` VALUES (100, 106); +INSERT INTO `sys_role_menu` VALUES (100, 107); +INSERT INTO `sys_role_menu` VALUES (100, 108); +INSERT INTO `sys_role_menu` VALUES (100, 109); +INSERT INTO `sys_role_menu` VALUES (100, 110); +INSERT INTO `sys_role_menu` VALUES (100, 111); +INSERT INTO `sys_role_menu` VALUES (100, 112); +INSERT INTO `sys_role_menu` VALUES (100, 113); +INSERT INTO `sys_role_menu` VALUES (100, 114); +INSERT INTO `sys_role_menu` VALUES (100, 115); +INSERT INTO `sys_role_menu` VALUES (100, 116); +INSERT INTO `sys_role_menu` VALUES (100, 117); +INSERT INTO `sys_role_menu` VALUES (100, 500); +INSERT INTO `sys_role_menu` VALUES (100, 501); +INSERT INTO `sys_role_menu` VALUES (100, 1000); +INSERT INTO `sys_role_menu` VALUES (100, 1001); +INSERT INTO `sys_role_menu` VALUES (100, 1002); +INSERT INTO `sys_role_menu` VALUES (100, 1003); +INSERT INTO `sys_role_menu` VALUES (100, 1004); +INSERT INTO `sys_role_menu` VALUES (100, 1005); +INSERT INTO `sys_role_menu` VALUES (100, 1006); +INSERT INTO `sys_role_menu` VALUES (100, 1007); +INSERT INTO `sys_role_menu` VALUES (100, 1008); +INSERT INTO `sys_role_menu` VALUES (100, 1009); +INSERT INTO `sys_role_menu` VALUES (100, 1010); +INSERT INTO `sys_role_menu` VALUES (100, 1011); +INSERT INTO `sys_role_menu` VALUES (100, 1012); +INSERT INTO `sys_role_menu` VALUES (100, 1013); +INSERT INTO `sys_role_menu` VALUES (100, 1014); +INSERT INTO `sys_role_menu` VALUES (100, 1015); +INSERT INTO `sys_role_menu` VALUES (100, 1016); +INSERT INTO `sys_role_menu` VALUES (100, 1017); +INSERT INTO `sys_role_menu` VALUES (100, 1018); +INSERT INTO `sys_role_menu` VALUES (100, 1019); +INSERT INTO `sys_role_menu` VALUES (100, 1020); +INSERT INTO `sys_role_menu` VALUES (100, 1021); +INSERT INTO `sys_role_menu` VALUES (100, 1022); +INSERT INTO `sys_role_menu` VALUES (100, 1023); +INSERT INTO `sys_role_menu` VALUES (100, 1024); +INSERT INTO `sys_role_menu` VALUES (100, 1025); +INSERT INTO `sys_role_menu` VALUES (100, 1026); +INSERT INTO `sys_role_menu` VALUES (100, 1027); +INSERT INTO `sys_role_menu` VALUES (100, 1028); +INSERT INTO `sys_role_menu` VALUES (100, 1029); +INSERT INTO `sys_role_menu` VALUES (100, 1030); +INSERT INTO `sys_role_menu` VALUES (100, 1031); +INSERT INTO `sys_role_menu` VALUES (100, 1032); +INSERT INTO `sys_role_menu` VALUES (100, 1033); +INSERT INTO `sys_role_menu` VALUES (100, 1034); +INSERT INTO `sys_role_menu` VALUES (100, 1035); +INSERT INTO `sys_role_menu` VALUES (100, 1036); +INSERT INTO `sys_role_menu` VALUES (100, 1037); +INSERT INTO `sys_role_menu` VALUES (100, 1038); +INSERT INTO `sys_role_menu` VALUES (100, 1039); +INSERT INTO `sys_role_menu` VALUES (100, 1040); +INSERT INTO `sys_role_menu` VALUES (100, 1041); +INSERT INTO `sys_role_menu` VALUES (100, 1042); +INSERT INTO `sys_role_menu` VALUES (100, 1043); +INSERT INTO `sys_role_menu` VALUES (100, 1044); +INSERT INTO `sys_role_menu` VALUES (100, 1045); +INSERT INTO `sys_role_menu` VALUES (100, 1046); +INSERT INTO `sys_role_menu` VALUES (100, 1047); +INSERT INTO `sys_role_menu` VALUES (100, 1048); +INSERT INTO `sys_role_menu` VALUES (100, 1049); +INSERT INTO `sys_role_menu` VALUES (100, 1050); +INSERT INTO `sys_role_menu` VALUES (100, 1051); +INSERT INTO `sys_role_menu` VALUES (100, 1052); +INSERT INTO `sys_role_menu` VALUES (100, 1053); +INSERT INTO `sys_role_menu` VALUES (100, 1054); +INSERT INTO `sys_role_menu` VALUES (100, 1055); +INSERT INTO `sys_role_menu` VALUES (100, 1056); +INSERT INTO `sys_role_menu` VALUES (100, 1057); +INSERT INTO `sys_role_menu` VALUES (100, 1058); +INSERT INTO `sys_role_menu` VALUES (100, 1059); +INSERT INTO `sys_role_menu` VALUES (100, 1060); +INSERT INTO `sys_role_menu` VALUES (100, 2000); +INSERT INTO `sys_role_menu` VALUES (100, 2001); +INSERT INTO `sys_role_menu` VALUES (100, 2002); +INSERT INTO `sys_role_menu` VALUES (100, 2003); +INSERT INTO `sys_role_menu` VALUES (100, 2004); +INSERT INTO `sys_role_menu` VALUES (100, 2005); +INSERT INTO `sys_role_menu` VALUES (100, 2006); +INSERT INTO `sys_role_menu` VALUES (100, 2007); +INSERT INTO `sys_role_menu` VALUES (100, 2008); +INSERT INTO `sys_role_menu` VALUES (100, 2009); +INSERT INTO `sys_role_menu` VALUES (100, 2010); +INSERT INTO `sys_role_menu` VALUES (100, 2011); +INSERT INTO `sys_role_menu` VALUES (100, 2012); +INSERT INTO `sys_role_menu` VALUES (100, 2013); +INSERT INTO `sys_role_menu` VALUES (100, 2014); +INSERT INTO `sys_role_menu` VALUES (100, 2015); +INSERT INTO `sys_role_menu` VALUES (100, 2016); +INSERT INTO `sys_role_menu` VALUES (100, 2017); +INSERT INTO `sys_role_menu` VALUES (100, 2018); +INSERT INTO `sys_role_menu` VALUES (100, 2019); +INSERT INTO `sys_role_menu` VALUES (100, 2020); +INSERT INTO `sys_role_menu` VALUES (100, 2021); +INSERT INTO `sys_role_menu` VALUES (100, 2022); +INSERT INTO `sys_role_menu` VALUES (100, 2023); +INSERT INTO `sys_role_menu` VALUES (100, 2024); +INSERT INTO `sys_role_menu` VALUES (100, 2025); +INSERT INTO `sys_role_menu` VALUES (100, 2026); +INSERT INTO `sys_role_menu` VALUES (100, 2027); +INSERT INTO `sys_role_menu` VALUES (100, 2028); +INSERT INTO `sys_role_menu` VALUES (100, 2035); +INSERT INTO `sys_role_menu` VALUES (100, 2036); +INSERT INTO `sys_role_menu` VALUES (100, 2037); +INSERT INTO `sys_role_menu` VALUES (100, 2038); +INSERT INTO `sys_role_menu` VALUES (100, 2039); +INSERT INTO `sys_role_menu` VALUES (100, 2040); +INSERT INTO `sys_role_menu` VALUES (100, 2041); +INSERT INTO `sys_role_menu` VALUES (100, 2042); +INSERT INTO `sys_role_menu` VALUES (100, 2043); +INSERT INTO `sys_role_menu` VALUES (100, 2044); +INSERT INTO `sys_role_menu` VALUES (100, 2045); +INSERT INTO `sys_role_menu` VALUES (100, 2046); +INSERT INTO `sys_role_menu` VALUES (100, 2047); +INSERT INTO `sys_role_menu` VALUES (100, 2048); +INSERT INTO `sys_role_menu` VALUES (100, 2054); +INSERT INTO `sys_role_menu` VALUES (101, 1); +INSERT INTO `sys_role_menu` VALUES (101, 2); +INSERT INTO `sys_role_menu` VALUES (101, 3); +INSERT INTO `sys_role_menu` VALUES (101, 100); +INSERT INTO `sys_role_menu` VALUES (101, 101); +INSERT INTO `sys_role_menu` VALUES (101, 102); +INSERT INTO `sys_role_menu` VALUES (101, 103); +INSERT INTO `sys_role_menu` VALUES (101, 104); +INSERT INTO `sys_role_menu` VALUES (101, 105); +INSERT INTO `sys_role_menu` VALUES (101, 106); +INSERT INTO `sys_role_menu` VALUES (101, 107); +INSERT INTO `sys_role_menu` VALUES (101, 108); +INSERT INTO `sys_role_menu` VALUES (101, 109); +INSERT INTO `sys_role_menu` VALUES (101, 110); +INSERT INTO `sys_role_menu` VALUES (101, 111); +INSERT INTO `sys_role_menu` VALUES (101, 112); +INSERT INTO `sys_role_menu` VALUES (101, 113); +INSERT INTO `sys_role_menu` VALUES (101, 114); +INSERT INTO `sys_role_menu` VALUES (101, 115); +INSERT INTO `sys_role_menu` VALUES (101, 116); +INSERT INTO `sys_role_menu` VALUES (101, 117); +INSERT INTO `sys_role_menu` VALUES (101, 500); +INSERT INTO `sys_role_menu` VALUES (101, 501); +INSERT INTO `sys_role_menu` VALUES (101, 1000); +INSERT INTO `sys_role_menu` VALUES (101, 1001); +INSERT INTO `sys_role_menu` VALUES (101, 1002); +INSERT INTO `sys_role_menu` VALUES (101, 1003); +INSERT INTO `sys_role_menu` VALUES (101, 1004); +INSERT INTO `sys_role_menu` VALUES (101, 1005); +INSERT INTO `sys_role_menu` VALUES (101, 1006); +INSERT INTO `sys_role_menu` VALUES (101, 1007); +INSERT INTO `sys_role_menu` VALUES (101, 1008); +INSERT INTO `sys_role_menu` VALUES (101, 1009); +INSERT INTO `sys_role_menu` VALUES (101, 1010); +INSERT INTO `sys_role_menu` VALUES (101, 1011); +INSERT INTO `sys_role_menu` VALUES (101, 1012); +INSERT INTO `sys_role_menu` VALUES (101, 1013); +INSERT INTO `sys_role_menu` VALUES (101, 1014); +INSERT INTO `sys_role_menu` VALUES (101, 1015); +INSERT INTO `sys_role_menu` VALUES (101, 1016); +INSERT INTO `sys_role_menu` VALUES (101, 1017); +INSERT INTO `sys_role_menu` VALUES (101, 1018); +INSERT INTO `sys_role_menu` VALUES (101, 1019); +INSERT INTO `sys_role_menu` VALUES (101, 1020); +INSERT INTO `sys_role_menu` VALUES (101, 1021); +INSERT INTO `sys_role_menu` VALUES (101, 1022); +INSERT INTO `sys_role_menu` VALUES (101, 1023); +INSERT INTO `sys_role_menu` VALUES (101, 1024); +INSERT INTO `sys_role_menu` VALUES (101, 1025); +INSERT INTO `sys_role_menu` VALUES (101, 1026); +INSERT INTO `sys_role_menu` VALUES (101, 1027); +INSERT INTO `sys_role_menu` VALUES (101, 1028); +INSERT INTO `sys_role_menu` VALUES (101, 1029); +INSERT INTO `sys_role_menu` VALUES (101, 1030); +INSERT INTO `sys_role_menu` VALUES (101, 1031); +INSERT INTO `sys_role_menu` VALUES (101, 1032); +INSERT INTO `sys_role_menu` VALUES (101, 1033); +INSERT INTO `sys_role_menu` VALUES (101, 1034); +INSERT INTO `sys_role_menu` VALUES (101, 1035); +INSERT INTO `sys_role_menu` VALUES (101, 1036); +INSERT INTO `sys_role_menu` VALUES (101, 1037); +INSERT INTO `sys_role_menu` VALUES (101, 1038); +INSERT INTO `sys_role_menu` VALUES (101, 1039); +INSERT INTO `sys_role_menu` VALUES (101, 1040); +INSERT INTO `sys_role_menu` VALUES (101, 1041); +INSERT INTO `sys_role_menu` VALUES (101, 1042); +INSERT INTO `sys_role_menu` VALUES (101, 1043); +INSERT INTO `sys_role_menu` VALUES (101, 1044); +INSERT INTO `sys_role_menu` VALUES (101, 1045); +INSERT INTO `sys_role_menu` VALUES (101, 1046); +INSERT INTO `sys_role_menu` VALUES (101, 1047); +INSERT INTO `sys_role_menu` VALUES (101, 1048); +INSERT INTO `sys_role_menu` VALUES (101, 1049); +INSERT INTO `sys_role_menu` VALUES (101, 1050); +INSERT INTO `sys_role_menu` VALUES (101, 1051); +INSERT INTO `sys_role_menu` VALUES (101, 1052); +INSERT INTO `sys_role_menu` VALUES (101, 1053); +INSERT INTO `sys_role_menu` VALUES (101, 1054); +INSERT INTO `sys_role_menu` VALUES (101, 1055); +INSERT INTO `sys_role_menu` VALUES (101, 1056); +INSERT INTO `sys_role_menu` VALUES (101, 1057); +INSERT INTO `sys_role_menu` VALUES (101, 1058); +INSERT INTO `sys_role_menu` VALUES (101, 1059); +INSERT INTO `sys_role_menu` VALUES (101, 1060); +INSERT INTO `sys_role_menu` VALUES (101, 2000); +INSERT INTO `sys_role_menu` VALUES (101, 2001); +INSERT INTO `sys_role_menu` VALUES (101, 2002); +INSERT INTO `sys_role_menu` VALUES (101, 2003); +INSERT INTO `sys_role_menu` VALUES (101, 2004); +INSERT INTO `sys_role_menu` VALUES (101, 2005); +INSERT INTO `sys_role_menu` VALUES (101, 2006); +INSERT INTO `sys_role_menu` VALUES (101, 2007); +INSERT INTO `sys_role_menu` VALUES (101, 2008); +INSERT INTO `sys_role_menu` VALUES (101, 2009); +INSERT INTO `sys_role_menu` VALUES (101, 2010); +INSERT INTO `sys_role_menu` VALUES (101, 2011); +INSERT INTO `sys_role_menu` VALUES (101, 2012); +INSERT INTO `sys_role_menu` VALUES (101, 2013); +INSERT INTO `sys_role_menu` VALUES (101, 2014); +INSERT INTO `sys_role_menu` VALUES (101, 2015); +INSERT INTO `sys_role_menu` VALUES (101, 2016); +INSERT INTO `sys_role_menu` VALUES (101, 2017); +INSERT INTO `sys_role_menu` VALUES (101, 2018); +INSERT INTO `sys_role_menu` VALUES (101, 2019); +INSERT INTO `sys_role_menu` VALUES (101, 2020); +INSERT INTO `sys_role_menu` VALUES (101, 2021); +INSERT INTO `sys_role_menu` VALUES (101, 2022); +INSERT INTO `sys_role_menu` VALUES (101, 2023); +INSERT INTO `sys_role_menu` VALUES (101, 2024); +INSERT INTO `sys_role_menu` VALUES (101, 2025); +INSERT INTO `sys_role_menu` VALUES (101, 2026); +INSERT INTO `sys_role_menu` VALUES (101, 2027); +INSERT INTO `sys_role_menu` VALUES (101, 2028); +INSERT INTO `sys_role_menu` VALUES (101, 2035); +INSERT INTO `sys_role_menu` VALUES (101, 2036); +INSERT INTO `sys_role_menu` VALUES (101, 2037); +INSERT INTO `sys_role_menu` VALUES (101, 2038); +INSERT INTO `sys_role_menu` VALUES (101, 2039); +INSERT INTO `sys_role_menu` VALUES (101, 2040); +INSERT INTO `sys_role_menu` VALUES (101, 2041); +INSERT INTO `sys_role_menu` VALUES (101, 2042); +INSERT INTO `sys_role_menu` VALUES (101, 2043); +INSERT INTO `sys_role_menu` VALUES (101, 2044); +INSERT INTO `sys_role_menu` VALUES (101, 2045); +INSERT INTO `sys_role_menu` VALUES (101, 2046); +INSERT INTO `sys_role_menu` VALUES (101, 2047); +INSERT INTO `sys_role_menu` VALUES (101, 2048); +INSERT INTO `sys_role_menu` VALUES (101, 2054); +INSERT INTO `sys_role_menu` VALUES (102, 1); +INSERT INTO `sys_role_menu` VALUES (102, 2); +INSERT INTO `sys_role_menu` VALUES (102, 3); +INSERT INTO `sys_role_menu` VALUES (102, 100); +INSERT INTO `sys_role_menu` VALUES (102, 101); +INSERT INTO `sys_role_menu` VALUES (102, 102); +INSERT INTO `sys_role_menu` VALUES (102, 103); +INSERT INTO `sys_role_menu` VALUES (102, 104); +INSERT INTO `sys_role_menu` VALUES (102, 105); +INSERT INTO `sys_role_menu` VALUES (102, 106); +INSERT INTO `sys_role_menu` VALUES (102, 107); +INSERT INTO `sys_role_menu` VALUES (102, 108); +INSERT INTO `sys_role_menu` VALUES (102, 109); +INSERT INTO `sys_role_menu` VALUES (102, 110); +INSERT INTO `sys_role_menu` VALUES (102, 111); +INSERT INTO `sys_role_menu` VALUES (102, 112); +INSERT INTO `sys_role_menu` VALUES (102, 113); +INSERT INTO `sys_role_menu` VALUES (102, 114); +INSERT INTO `sys_role_menu` VALUES (102, 115); +INSERT INTO `sys_role_menu` VALUES (102, 116); +INSERT INTO `sys_role_menu` VALUES (102, 117); +INSERT INTO `sys_role_menu` VALUES (102, 500); +INSERT INTO `sys_role_menu` VALUES (102, 501); +INSERT INTO `sys_role_menu` VALUES (102, 1000); +INSERT INTO `sys_role_menu` VALUES (102, 1001); +INSERT INTO `sys_role_menu` VALUES (102, 1002); +INSERT INTO `sys_role_menu` VALUES (102, 1003); +INSERT INTO `sys_role_menu` VALUES (102, 1004); +INSERT INTO `sys_role_menu` VALUES (102, 1005); +INSERT INTO `sys_role_menu` VALUES (102, 1006); +INSERT INTO `sys_role_menu` VALUES (102, 1007); +INSERT INTO `sys_role_menu` VALUES (102, 1008); +INSERT INTO `sys_role_menu` VALUES (102, 1009); +INSERT INTO `sys_role_menu` VALUES (102, 1010); +INSERT INTO `sys_role_menu` VALUES (102, 1011); +INSERT INTO `sys_role_menu` VALUES (102, 1012); +INSERT INTO `sys_role_menu` VALUES (102, 1013); +INSERT INTO `sys_role_menu` VALUES (102, 1014); +INSERT INTO `sys_role_menu` VALUES (102, 1015); +INSERT INTO `sys_role_menu` VALUES (102, 1016); +INSERT INTO `sys_role_menu` VALUES (102, 1017); +INSERT INTO `sys_role_menu` VALUES (102, 1018); +INSERT INTO `sys_role_menu` VALUES (102, 1019); +INSERT INTO `sys_role_menu` VALUES (102, 1020); +INSERT INTO `sys_role_menu` VALUES (102, 1021); +INSERT INTO `sys_role_menu` VALUES (102, 1022); +INSERT INTO `sys_role_menu` VALUES (102, 1023); +INSERT INTO `sys_role_menu` VALUES (102, 1024); +INSERT INTO `sys_role_menu` VALUES (102, 1025); +INSERT INTO `sys_role_menu` VALUES (102, 1026); +INSERT INTO `sys_role_menu` VALUES (102, 1027); +INSERT INTO `sys_role_menu` VALUES (102, 1028); +INSERT INTO `sys_role_menu` VALUES (102, 1029); +INSERT INTO `sys_role_menu` VALUES (102, 1030); +INSERT INTO `sys_role_menu` VALUES (102, 1031); +INSERT INTO `sys_role_menu` VALUES (102, 1032); +INSERT INTO `sys_role_menu` VALUES (102, 1033); +INSERT INTO `sys_role_menu` VALUES (102, 1034); +INSERT INTO `sys_role_menu` VALUES (102, 1035); +INSERT INTO `sys_role_menu` VALUES (102, 1036); +INSERT INTO `sys_role_menu` VALUES (102, 1037); +INSERT INTO `sys_role_menu` VALUES (102, 1038); +INSERT INTO `sys_role_menu` VALUES (102, 1039); +INSERT INTO `sys_role_menu` VALUES (102, 1040); +INSERT INTO `sys_role_menu` VALUES (102, 1041); +INSERT INTO `sys_role_menu` VALUES (102, 1042); +INSERT INTO `sys_role_menu` VALUES (102, 1043); +INSERT INTO `sys_role_menu` VALUES (102, 1044); +INSERT INTO `sys_role_menu` VALUES (102, 1045); +INSERT INTO `sys_role_menu` VALUES (102, 1046); +INSERT INTO `sys_role_menu` VALUES (102, 1047); +INSERT INTO `sys_role_menu` VALUES (102, 1048); +INSERT INTO `sys_role_menu` VALUES (102, 1049); +INSERT INTO `sys_role_menu` VALUES (102, 1050); +INSERT INTO `sys_role_menu` VALUES (102, 1051); +INSERT INTO `sys_role_menu` VALUES (102, 1052); +INSERT INTO `sys_role_menu` VALUES (102, 1053); +INSERT INTO `sys_role_menu` VALUES (102, 1054); +INSERT INTO `sys_role_menu` VALUES (102, 1055); +INSERT INTO `sys_role_menu` VALUES (102, 1056); +INSERT INTO `sys_role_menu` VALUES (102, 1057); +INSERT INTO `sys_role_menu` VALUES (102, 1058); +INSERT INTO `sys_role_menu` VALUES (102, 1059); +INSERT INTO `sys_role_menu` VALUES (102, 1060); +INSERT INTO `sys_role_menu` VALUES (102, 2000); +INSERT INTO `sys_role_menu` VALUES (102, 2001); +INSERT INTO `sys_role_menu` VALUES (102, 2002); +INSERT INTO `sys_role_menu` VALUES (102, 2003); +INSERT INTO `sys_role_menu` VALUES (102, 2004); +INSERT INTO `sys_role_menu` VALUES (102, 2005); +INSERT INTO `sys_role_menu` VALUES (102, 2006); +INSERT INTO `sys_role_menu` VALUES (102, 2007); +INSERT INTO `sys_role_menu` VALUES (102, 2008); +INSERT INTO `sys_role_menu` VALUES (102, 2009); +INSERT INTO `sys_role_menu` VALUES (102, 2010); +INSERT INTO `sys_role_menu` VALUES (102, 2011); +INSERT INTO `sys_role_menu` VALUES (102, 2012); +INSERT INTO `sys_role_menu` VALUES (102, 2013); +INSERT INTO `sys_role_menu` VALUES (102, 2014); +INSERT INTO `sys_role_menu` VALUES (102, 2015); +INSERT INTO `sys_role_menu` VALUES (102, 2016); +INSERT INTO `sys_role_menu` VALUES (102, 2017); +INSERT INTO `sys_role_menu` VALUES (102, 2018); +INSERT INTO `sys_role_menu` VALUES (102, 2019); +INSERT INTO `sys_role_menu` VALUES (102, 2020); +INSERT INTO `sys_role_menu` VALUES (102, 2021); +INSERT INTO `sys_role_menu` VALUES (102, 2022); +INSERT INTO `sys_role_menu` VALUES (102, 2023); +INSERT INTO `sys_role_menu` VALUES (102, 2024); +INSERT INTO `sys_role_menu` VALUES (102, 2025); +INSERT INTO `sys_role_menu` VALUES (102, 2026); +INSERT INTO `sys_role_menu` VALUES (102, 2027); +INSERT INTO `sys_role_menu` VALUES (102, 2028); +INSERT INTO `sys_role_menu` VALUES (102, 2035); +INSERT INTO `sys_role_menu` VALUES (102, 2036); +INSERT INTO `sys_role_menu` VALUES (102, 2037); +INSERT INTO `sys_role_menu` VALUES (102, 2038); +INSERT INTO `sys_role_menu` VALUES (102, 2039); +INSERT INTO `sys_role_menu` VALUES (102, 2040); +INSERT INTO `sys_role_menu` VALUES (102, 2041); +INSERT INTO `sys_role_menu` VALUES (102, 2042); +INSERT INTO `sys_role_menu` VALUES (102, 2043); +INSERT INTO `sys_role_menu` VALUES (102, 2044); +INSERT INTO `sys_role_menu` VALUES (102, 2045); +INSERT INTO `sys_role_menu` VALUES (102, 2046); +INSERT INTO `sys_role_menu` VALUES (102, 2047); +INSERT INTO `sys_role_menu` VALUES (102, 2048); +INSERT INTO `sys_role_menu` VALUES (102, 2054); +INSERT INTO `sys_role_menu` VALUES (103, 1); +INSERT INTO `sys_role_menu` VALUES (103, 2); +INSERT INTO `sys_role_menu` VALUES (103, 3); +INSERT INTO `sys_role_menu` VALUES (103, 100); +INSERT INTO `sys_role_menu` VALUES (103, 101); +INSERT INTO `sys_role_menu` VALUES (103, 102); +INSERT INTO `sys_role_menu` VALUES (103, 103); +INSERT INTO `sys_role_menu` VALUES (103, 104); +INSERT INTO `sys_role_menu` VALUES (103, 105); +INSERT INTO `sys_role_menu` VALUES (103, 106); +INSERT INTO `sys_role_menu` VALUES (103, 107); +INSERT INTO `sys_role_menu` VALUES (103, 108); +INSERT INTO `sys_role_menu` VALUES (103, 109); +INSERT INTO `sys_role_menu` VALUES (103, 110); +INSERT INTO `sys_role_menu` VALUES (103, 111); +INSERT INTO `sys_role_menu` VALUES (103, 112); +INSERT INTO `sys_role_menu` VALUES (103, 113); +INSERT INTO `sys_role_menu` VALUES (103, 114); +INSERT INTO `sys_role_menu` VALUES (103, 115); +INSERT INTO `sys_role_menu` VALUES (103, 116); +INSERT INTO `sys_role_menu` VALUES (103, 117); +INSERT INTO `sys_role_menu` VALUES (103, 500); +INSERT INTO `sys_role_menu` VALUES (103, 501); +INSERT INTO `sys_role_menu` VALUES (103, 1000); +INSERT INTO `sys_role_menu` VALUES (103, 1001); +INSERT INTO `sys_role_menu` VALUES (103, 1002); +INSERT INTO `sys_role_menu` VALUES (103, 1003); +INSERT INTO `sys_role_menu` VALUES (103, 1004); +INSERT INTO `sys_role_menu` VALUES (103, 1005); +INSERT INTO `sys_role_menu` VALUES (103, 1006); +INSERT INTO `sys_role_menu` VALUES (103, 1007); +INSERT INTO `sys_role_menu` VALUES (103, 1008); +INSERT INTO `sys_role_menu` VALUES (103, 1009); +INSERT INTO `sys_role_menu` VALUES (103, 1010); +INSERT INTO `sys_role_menu` VALUES (103, 1011); +INSERT INTO `sys_role_menu` VALUES (103, 1012); +INSERT INTO `sys_role_menu` VALUES (103, 1013); +INSERT INTO `sys_role_menu` VALUES (103, 1014); +INSERT INTO `sys_role_menu` VALUES (103, 1015); +INSERT INTO `sys_role_menu` VALUES (103, 1016); +INSERT INTO `sys_role_menu` VALUES (103, 1017); +INSERT INTO `sys_role_menu` VALUES (103, 1018); +INSERT INTO `sys_role_menu` VALUES (103, 1019); +INSERT INTO `sys_role_menu` VALUES (103, 1020); +INSERT INTO `sys_role_menu` VALUES (103, 1021); +INSERT INTO `sys_role_menu` VALUES (103, 1022); +INSERT INTO `sys_role_menu` VALUES (103, 1023); +INSERT INTO `sys_role_menu` VALUES (103, 1024); +INSERT INTO `sys_role_menu` VALUES (103, 1025); +INSERT INTO `sys_role_menu` VALUES (103, 1026); +INSERT INTO `sys_role_menu` VALUES (103, 1027); +INSERT INTO `sys_role_menu` VALUES (103, 1028); +INSERT INTO `sys_role_menu` VALUES (103, 1029); +INSERT INTO `sys_role_menu` VALUES (103, 1030); +INSERT INTO `sys_role_menu` VALUES (103, 1031); +INSERT INTO `sys_role_menu` VALUES (103, 1032); +INSERT INTO `sys_role_menu` VALUES (103, 1033); +INSERT INTO `sys_role_menu` VALUES (103, 1034); +INSERT INTO `sys_role_menu` VALUES (103, 1035); +INSERT INTO `sys_role_menu` VALUES (103, 1036); +INSERT INTO `sys_role_menu` VALUES (103, 1037); +INSERT INTO `sys_role_menu` VALUES (103, 1038); +INSERT INTO `sys_role_menu` VALUES (103, 1039); +INSERT INTO `sys_role_menu` VALUES (103, 1040); +INSERT INTO `sys_role_menu` VALUES (103, 1041); +INSERT INTO `sys_role_menu` VALUES (103, 1042); +INSERT INTO `sys_role_menu` VALUES (103, 1043); +INSERT INTO `sys_role_menu` VALUES (103, 1044); +INSERT INTO `sys_role_menu` VALUES (103, 1045); +INSERT INTO `sys_role_menu` VALUES (103, 1046); +INSERT INTO `sys_role_menu` VALUES (103, 1047); +INSERT INTO `sys_role_menu` VALUES (103, 1048); +INSERT INTO `sys_role_menu` VALUES (103, 1049); +INSERT INTO `sys_role_menu` VALUES (103, 1050); +INSERT INTO `sys_role_menu` VALUES (103, 1051); +INSERT INTO `sys_role_menu` VALUES (103, 1052); +INSERT INTO `sys_role_menu` VALUES (103, 1053); +INSERT INTO `sys_role_menu` VALUES (103, 1054); +INSERT INTO `sys_role_menu` VALUES (103, 1055); +INSERT INTO `sys_role_menu` VALUES (103, 1056); +INSERT INTO `sys_role_menu` VALUES (103, 1057); +INSERT INTO `sys_role_menu` VALUES (103, 1058); +INSERT INTO `sys_role_menu` VALUES (103, 1059); +INSERT INTO `sys_role_menu` VALUES (103, 1060); +INSERT INTO `sys_role_menu` VALUES (103, 2000); +INSERT INTO `sys_role_menu` VALUES (103, 2001); +INSERT INTO `sys_role_menu` VALUES (103, 2002); +INSERT INTO `sys_role_menu` VALUES (103, 2003); +INSERT INTO `sys_role_menu` VALUES (103, 2004); +INSERT INTO `sys_role_menu` VALUES (103, 2005); +INSERT INTO `sys_role_menu` VALUES (103, 2006); +INSERT INTO `sys_role_menu` VALUES (103, 2007); +INSERT INTO `sys_role_menu` VALUES (103, 2008); +INSERT INTO `sys_role_menu` VALUES (103, 2009); +INSERT INTO `sys_role_menu` VALUES (103, 2010); +INSERT INTO `sys_role_menu` VALUES (103, 2011); +INSERT INTO `sys_role_menu` VALUES (103, 2012); +INSERT INTO `sys_role_menu` VALUES (103, 2013); +INSERT INTO `sys_role_menu` VALUES (103, 2014); +INSERT INTO `sys_role_menu` VALUES (103, 2015); +INSERT INTO `sys_role_menu` VALUES (103, 2016); +INSERT INTO `sys_role_menu` VALUES (103, 2017); +INSERT INTO `sys_role_menu` VALUES (103, 2018); +INSERT INTO `sys_role_menu` VALUES (103, 2019); +INSERT INTO `sys_role_menu` VALUES (103, 2020); +INSERT INTO `sys_role_menu` VALUES (103, 2021); +INSERT INTO `sys_role_menu` VALUES (103, 2022); +INSERT INTO `sys_role_menu` VALUES (103, 2023); +INSERT INTO `sys_role_menu` VALUES (103, 2024); +INSERT INTO `sys_role_menu` VALUES (103, 2025); +INSERT INTO `sys_role_menu` VALUES (103, 2026); +INSERT INTO `sys_role_menu` VALUES (103, 2027); +INSERT INTO `sys_role_menu` VALUES (103, 2028); +INSERT INTO `sys_role_menu` VALUES (103, 2035); +INSERT INTO `sys_role_menu` VALUES (103, 2036); +INSERT INTO `sys_role_menu` VALUES (103, 2037); +INSERT INTO `sys_role_menu` VALUES (103, 2038); +INSERT INTO `sys_role_menu` VALUES (103, 2039); +INSERT INTO `sys_role_menu` VALUES (103, 2040); +INSERT INTO `sys_role_menu` VALUES (103, 2041); +INSERT INTO `sys_role_menu` VALUES (103, 2042); +INSERT INTO `sys_role_menu` VALUES (103, 2043); +INSERT INTO `sys_role_menu` VALUES (103, 2044); +INSERT INTO `sys_role_menu` VALUES (103, 2045); +INSERT INTO `sys_role_menu` VALUES (103, 2046); +INSERT INTO `sys_role_menu` VALUES (103, 2047); +INSERT INTO `sys_role_menu` VALUES (103, 2048); +INSERT INTO `sys_role_menu` VALUES (103, 2054); + +-- ---------------------------- +-- Table structure for sys_user +-- ---------------------------- +DROP TABLE IF EXISTS `sys_user`; +CREATE TABLE `sys_user` ( + `user_id` bigint NOT NULL AUTO_INCREMENT COMMENT '用户ID', + `dept_id` bigint NULL DEFAULT NULL COMMENT '部门ID', + `user_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户账号', + `nick_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户昵称', + `user_type` varchar(2) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '00' COMMENT '用户类型(00系统用户)', + `email` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '用户邮箱', + `phonenumber` varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '手机号码', + `sex` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '0' COMMENT '用户性别(0男 1女 2未知)', + `avatar` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '头像地址', + `password` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '密码', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '0' COMMENT '帐号状态(0正常 1停用)', + `del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)', + `login_ip` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '最后登录IP', + `login_date` datetime NULL DEFAULT NULL COMMENT '最后登录时间', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`user_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 106 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '用户信息表' ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of sys_user +-- ---------------------------- +INSERT INTO `sys_user` VALUES (1, 103, 'admin', '若依', '00', 'ry@163.com', '15888888888', '1', '', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', '2025-03-02 09:58:31', 'admin', '2024-08-14 02:48:23', '', '2025-03-02 01:58:31', '管理员'); +INSERT INTO `sys_user` VALUES (2, 103, 'ry', '若依', '00', 'ry@qq.com', '15666666666', '1', '', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', '2024-08-14 02:48:23', 'admin', '2024-08-14 02:48:23', 'admin', '2024-10-18 10:10:07', '测试员'); +INSERT INTO `sys_user` VALUES (100, 103, 'guotianle', 'guotianle', '00', '', '18888888888', '0', '', '$2a$10$GhMQGKcwBXW43oekDfuSeuddpnBOXqUqRtLdRvGctnFZU4qRnjluK', '0', '2', '127.0.0.1', '2024-10-13 10:11:11', 'admin', '2024-10-13 02:10:30', '', '2024-10-13 02:11:10', NULL); +INSERT INTO `sys_user` VALUES (101, 201, 'xiaoqing', '小青', '00', '', '', '1', '', '$2a$10$Ggf5yLwf.HKHZdmu36ujNuWuBOMb8UhaHKWP.Q1h39AQCM.4Rp.Li', '0', '0', '127.0.0.1', '2024-10-18 18:31:55', 'admin', '2024-10-18 10:12:45', 'admin', '2024-11-03 16:11:29', NULL); +INSERT INTO `sys_user` VALUES (102, 201, 'xiaobai', '小白', '00', '', '', '1', '', '$2a$10$gTuSQuL2gCF7DRAog5CQi.f7X7aO4SE18V2EtDmKvUp0YNZKNw9Ou', '0', '0', '', NULL, 'admin', '2024-10-18 10:13:12', 'admin', '2024-11-03 16:11:36', NULL); +INSERT INTO `sys_user` VALUES (103, 202, 'laozhang', '老张', '00', '', '', '0', '', '$2a$10$vhgwrN3aGZB9q/lVhmfvDOQmkkB9Lo9B2MQjN2vytASPqmdVlCrlO', '0', '0', '', NULL, 'admin', '2024-10-18 10:13:41', 'admin', '2024-11-03 16:11:42', NULL); +INSERT INTO `sys_user` VALUES (104, 103, 'laowang', '老王', '00', '', '', '0', '', '$2a$10$78oaYzQz3g8JDZg.g6x31eZZvQj7AzViwUJP47s/zazNEGmGe7tbC', '0', '0', '', NULL, 'admin', '2024-10-18 10:13:59', 'admin', '2024-11-03 16:11:47', NULL); +INSERT INTO `sys_user` VALUES (105, 201, 'xuxian', '许仙', '00', '', '', '1', '', '$2a$10$8tu/vev69rM8rxAECsO8Qe5WQlFgyRSMEHmlY0jcOLWemHj/1rIvq', '0', '0', '', NULL, 'admin', '2024-10-19 01:27:15', 'admin', '2024-11-03 16:11:57', NULL); + +-- ---------------------------- +-- Table structure for sys_user_post +-- ---------------------------- +DROP TABLE IF EXISTS `sys_user_post`; +CREATE TABLE `sys_user_post` ( + `user_id` bigint NOT NULL COMMENT '用户ID', + `post_id` bigint NOT NULL COMMENT '岗位ID', + PRIMARY KEY (`user_id`, `post_id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '用户与岗位关联表' ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of sys_user_post +-- ---------------------------- +INSERT INTO `sys_user_post` VALUES (1, 1); +INSERT INTO `sys_user_post` VALUES (2, 2); +INSERT INTO `sys_user_post` VALUES (101, 4); +INSERT INTO `sys_user_post` VALUES (102, 4); +INSERT INTO `sys_user_post` VALUES (103, 4); +INSERT INTO `sys_user_post` VALUES (104, 1); +INSERT INTO `sys_user_post` VALUES (105, 4); + +-- ---------------------------- +-- Table structure for sys_user_role +-- ---------------------------- +DROP TABLE IF EXISTS `sys_user_role`; +CREATE TABLE `sys_user_role` ( + `user_id` bigint NOT NULL COMMENT '用户ID', + `role_id` bigint NOT NULL COMMENT '角色ID', + PRIMARY KEY (`user_id`, `role_id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '用户和角色关联表' ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of sys_user_role +-- ---------------------------- +INSERT INTO `sys_user_role` VALUES (1, 1); +INSERT INTO `sys_user_role` VALUES (2, 2); +INSERT INTO `sys_user_role` VALUES (101, 100); +INSERT INTO `sys_user_role` VALUES (102, 100); +INSERT INTO `sys_user_role` VALUES (103, 101); +INSERT INTO `sys_user_role` VALUES (104, 103); +INSERT INTO `sys_user_role` VALUES (105, 100); + +SET FOREIGN_KEY_CHECKS = 1; diff --git a/sql/quartz.sql b/sql/quartz.sql new file mode 100644 index 0000000..cee613b --- /dev/null +++ b/sql/quartz.sql @@ -0,0 +1,174 @@ +DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS; +DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE; +DROP TABLE IF EXISTS QRTZ_LOCKS; +DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_JOB_DETAILS; +DROP TABLE IF EXISTS QRTZ_CALENDARS; + +-- ---------------------------- +-- 1、存储每一个已配置的 jobDetail 的详细信息 +-- ---------------------------- +create table QRTZ_JOB_DETAILS ( + sched_name varchar(120) not null comment '调度名称', + job_name varchar(200) not null comment '任务名称', + job_group varchar(200) not null comment '任务组名', + description varchar(250) null comment '相关介绍', + job_class_name varchar(250) not null comment '执行任务类名称', + is_durable varchar(1) not null comment '是否持久化', + is_nonconcurrent varchar(1) not null comment '是否并发', + is_update_data varchar(1) not null comment '是否更新数据', + requests_recovery varchar(1) not null comment '是否接受恢复执行', + job_data blob null comment '存放持久化job对象', + primary key (sched_name, job_name, job_group) +) engine=innodb comment = '任务详细信息表'; + +-- ---------------------------- +-- 2、 存储已配置的 Trigger 的信息 +-- ---------------------------- +create table QRTZ_TRIGGERS ( + sched_name varchar(120) not null comment '调度名称', + trigger_name varchar(200) not null comment '触发器的名字', + trigger_group varchar(200) not null comment '触发器所属组的名字', + job_name varchar(200) not null comment 'qrtz_job_details表job_name的外键', + job_group varchar(200) not null comment 'qrtz_job_details表job_group的外键', + description varchar(250) null comment '相关介绍', + next_fire_time bigint(13) null comment '上一次触发时间(毫秒)', + prev_fire_time bigint(13) null comment '下一次触发时间(默认为-1表示不触发)', + priority integer null comment '优先级', + trigger_state varchar(16) not null comment '触发器状态', + trigger_type varchar(8) not null comment '触发器的类型', + start_time bigint(13) not null comment '开始时间', + end_time bigint(13) null comment '结束时间', + calendar_name varchar(200) null comment '日程表名称', + misfire_instr smallint(2) null comment '补偿执行的策略', + job_data blob null comment '存放持久化job对象', + primary key (sched_name, trigger_name, trigger_group), + foreign key (sched_name, job_name, job_group) references QRTZ_JOB_DETAILS(sched_name, job_name, job_group) +) engine=innodb comment = '触发器详细信息表'; + +-- ---------------------------- +-- 3、 存储简单的 Trigger,包括重复次数,间隔,以及已触发的次数 +-- ---------------------------- +create table QRTZ_SIMPLE_TRIGGERS ( + sched_name varchar(120) not null comment '调度名称', + trigger_name varchar(200) not null comment 'qrtz_triggers表trigger_name的外键', + trigger_group varchar(200) not null comment 'qrtz_triggers表trigger_group的外键', + repeat_count bigint(7) not null comment '重复的次数统计', + repeat_interval bigint(12) not null comment '重复的间隔时间', + times_triggered bigint(10) not null comment '已经触发的次数', + primary key (sched_name, trigger_name, trigger_group), + foreign key (sched_name, trigger_name, trigger_group) references QRTZ_TRIGGERS(sched_name, trigger_name, trigger_group) +) engine=innodb comment = '简单触发器的信息表'; + +-- ---------------------------- +-- 4、 存储 Cron Trigger,包括 Cron 表达式和时区信息 +-- ---------------------------- +create table QRTZ_CRON_TRIGGERS ( + sched_name varchar(120) not null comment '调度名称', + trigger_name varchar(200) not null comment 'qrtz_triggers表trigger_name的外键', + trigger_group varchar(200) not null comment 'qrtz_triggers表trigger_group的外键', + cron_expression varchar(200) not null comment 'cron表达式', + time_zone_id varchar(80) comment '时区', + primary key (sched_name, trigger_name, trigger_group), + foreign key (sched_name, trigger_name, trigger_group) references QRTZ_TRIGGERS(sched_name, trigger_name, trigger_group) +) engine=innodb comment = 'Cron类型的触发器表'; + +-- ---------------------------- +-- 5、 Trigger 作为 Blob 类型存储(用于 Quartz 用户用 JDBC 创建他们自己定制的 Trigger 类型,JobStore 并不知道如何存储实例的时候) +-- ---------------------------- +create table QRTZ_BLOB_TRIGGERS ( + sched_name varchar(120) not null comment '调度名称', + trigger_name varchar(200) not null comment 'qrtz_triggers表trigger_name的外键', + trigger_group varchar(200) not null comment 'qrtz_triggers表trigger_group的外键', + blob_data blob null comment '存放持久化Trigger对象', + primary key (sched_name, trigger_name, trigger_group), + foreign key (sched_name, trigger_name, trigger_group) references QRTZ_TRIGGERS(sched_name, trigger_name, trigger_group) +) engine=innodb comment = 'Blob类型的触发器表'; + +-- ---------------------------- +-- 6、 以 Blob 类型存储存放日历信息, quartz可配置一个日历来指定一个时间范围 +-- ---------------------------- +create table QRTZ_CALENDARS ( + sched_name varchar(120) not null comment '调度名称', + calendar_name varchar(200) not null comment '日历名称', + calendar blob not null comment '存放持久化calendar对象', + primary key (sched_name, calendar_name) +) engine=innodb comment = '日历信息表'; + +-- ---------------------------- +-- 7、 存储已暂停的 Trigger 组的信息 +-- ---------------------------- +create table QRTZ_PAUSED_TRIGGER_GRPS ( + sched_name varchar(120) not null comment '调度名称', + trigger_group varchar(200) not null comment 'qrtz_triggers表trigger_group的外键', + primary key (sched_name, trigger_group) +) engine=innodb comment = '暂停的触发器表'; + +-- ---------------------------- +-- 8、 存储与已触发的 Trigger 相关的状态信息,以及相联 Job 的执行信息 +-- ---------------------------- +create table QRTZ_FIRED_TRIGGERS ( + sched_name varchar(120) not null comment '调度名称', + entry_id varchar(95) not null comment '调度器实例id', + trigger_name varchar(200) not null comment 'qrtz_triggers表trigger_name的外键', + trigger_group varchar(200) not null comment 'qrtz_triggers表trigger_group的外键', + instance_name varchar(200) not null comment '调度器实例名', + fired_time bigint(13) not null comment '触发的时间', + sched_time bigint(13) not null comment '定时器制定的时间', + priority integer not null comment '优先级', + state varchar(16) not null comment '状态', + job_name varchar(200) null comment '任务名称', + job_group varchar(200) null comment '任务组名', + is_nonconcurrent varchar(1) null comment '是否并发', + requests_recovery varchar(1) null comment '是否接受恢复执行', + primary key (sched_name, entry_id) +) engine=innodb comment = '已触发的触发器表'; + +-- ---------------------------- +-- 9、 存储少量的有关 Scheduler 的状态信息,假如是用于集群中,可以看到其他的 Scheduler 实例 +-- ---------------------------- +create table QRTZ_SCHEDULER_STATE ( + sched_name varchar(120) not null comment '调度名称', + instance_name varchar(200) not null comment '实例名称', + last_checkin_time bigint(13) not null comment '上次检查时间', + checkin_interval bigint(13) not null comment '检查间隔时间', + primary key (sched_name, instance_name) +) engine=innodb comment = '调度器状态表'; + +-- ---------------------------- +-- 10、 存储程序的悲观锁的信息(假如使用了悲观锁) +-- ---------------------------- +create table QRTZ_LOCKS ( + sched_name varchar(120) not null comment '调度名称', + lock_name varchar(40) not null comment '悲观锁名称', + primary key (sched_name, lock_name) +) engine=innodb comment = '存储的悲观锁信息表'; + +-- ---------------------------- +-- 11、 Quartz集群实现同步机制的行锁表 +-- ---------------------------- +create table QRTZ_SIMPROP_TRIGGERS ( + sched_name varchar(120) not null comment '调度名称', + trigger_name varchar(200) not null comment 'qrtz_triggers表trigger_name的外键', + trigger_group varchar(200) not null comment 'qrtz_triggers表trigger_group的外键', + str_prop_1 varchar(512) null comment 'String类型的trigger的第一个参数', + str_prop_2 varchar(512) null comment 'String类型的trigger的第二个参数', + str_prop_3 varchar(512) null comment 'String类型的trigger的第三个参数', + int_prop_1 int null comment 'int类型的trigger的第一个参数', + int_prop_2 int null comment 'int类型的trigger的第二个参数', + long_prop_1 bigint null comment 'long类型的trigger的第一个参数', + long_prop_2 bigint null comment 'long类型的trigger的第二个参数', + dec_prop_1 numeric(13,4) null comment 'decimal类型的trigger的第一个参数', + dec_prop_2 numeric(13,4) null comment 'decimal类型的trigger的第二个参数', + bool_prop_1 varchar(1) null comment 'Boolean类型的trigger的第一个参数', + bool_prop_2 varchar(1) null comment 'Boolean类型的trigger的第二个参数', + primary key (sched_name, trigger_name, trigger_group), + foreign key (sched_name, trigger_name, trigger_group) references QRTZ_TRIGGERS(sched_name, trigger_name, trigger_group) +) engine=innodb comment = '同步机制的行锁表'; + +commit; \ No newline at end of file diff --git a/sql/ry_20240629.sql b/sql/ry_20240629.sql new file mode 100644 index 0000000..e782428 --- /dev/null +++ b/sql/ry_20240629.sql @@ -0,0 +1,704 @@ +create database if not exists zzyl; +use zzyl; + +-- ---------------------------- +-- 1、部门表 +-- ---------------------------- +drop table if exists sys_dept; +create table sys_dept ( + dept_id bigint(20) not null auto_increment comment '部门id', + parent_id bigint(20) default 0 comment '父部门id', + ancestors varchar(50) default '' comment '祖级列表', + dept_name varchar(30) default '' comment '部门名称', + order_num int(4) default 0 comment '显示顺序', + leader varchar(20) default null comment '负责人', + phone varchar(11) default null comment '联系电话', + email varchar(50) default null comment '邮箱', + status char(1) default '0' comment '部门状态(0正常 1停用)', + del_flag char(1) default '0' comment '删除标志(0代表存在 2代表删除)', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + primary key (dept_id) +) engine=innodb auto_increment=200 comment = '部门表'; + +-- ---------------------------- +-- 初始化-部门表数据 +-- ---------------------------- +insert into sys_dept values(100, 0, '0', '若依科技', 0, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); +insert into sys_dept values(101, 100, '0,100', '深圳总公司', 1, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); +insert into sys_dept values(102, 100, '0,100', '长沙分公司', 2, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); +insert into sys_dept values(103, 101, '0,100,101', '研发部门', 1, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); +insert into sys_dept values(104, 101, '0,100,101', '市场部门', 2, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); +insert into sys_dept values(105, 101, '0,100,101', '测试部门', 3, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); +insert into sys_dept values(106, 101, '0,100,101', '财务部门', 4, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); +insert into sys_dept values(107, 101, '0,100,101', '运维部门', 5, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); +insert into sys_dept values(108, 102, '0,100,102', '市场部门', 1, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); +insert into sys_dept values(109, 102, '0,100,102', '财务部门', 2, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', sysdate(), '', null); + + +-- ---------------------------- +-- 2、用户信息表 +-- ---------------------------- +drop table if exists sys_user; +create table sys_user ( + user_id bigint(20) not null auto_increment comment '用户ID', + dept_id bigint(20) default null comment '部门ID', + user_name varchar(30) not null comment '用户账号', + nick_name varchar(30) not null comment '用户昵称', + user_type varchar(2) default '00' comment '用户类型(00系统用户)', + email varchar(50) default '' comment '用户邮箱', + phonenumber varchar(11) default '' comment '手机号码', + sex char(1) default '0' comment '用户性别(0男 1女 2未知)', + avatar varchar(100) default '' comment '头像地址', + password varchar(100) default '' comment '密码', + status char(1) default '0' comment '帐号状态(0正常 1停用)', + del_flag char(1) default '0' comment '删除标志(0代表存在 2代表删除)', + login_ip varchar(128) default '' comment '最后登录IP', + login_date datetime comment '最后登录时间', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + remark varchar(500) default null comment '备注', + primary key (user_id) +) engine=innodb auto_increment=100 comment = '用户信息表'; + +-- ---------------------------- +-- 初始化-用户信息表数据 +-- ---------------------------- +insert into sys_user values(1, 103, 'admin', '若依', '00', 'ry@163.com', '15888888888', '1', '', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', sysdate(), 'admin', sysdate(), '', null, '管理员'); +insert into sys_user values(2, 105, 'ry', '若依', '00', 'ry@qq.com', '15666666666', '1', '', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', sysdate(), 'admin', sysdate(), '', null, '测试员'); + + +-- ---------------------------- +-- 3、岗位信息表 +-- ---------------------------- +drop table if exists sys_post; +create table sys_post +( + post_id bigint(20) not null auto_increment comment '岗位ID', + post_code varchar(64) not null comment '岗位编码', + post_name varchar(50) not null comment '岗位名称', + post_sort int(4) not null comment '显示顺序', + status char(1) not null comment '状态(0正常 1停用)', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + remark varchar(500) default null comment '备注', + primary key (post_id) +) engine=innodb comment = '岗位信息表'; + +-- ---------------------------- +-- 初始化-岗位信息表数据 +-- ---------------------------- +insert into sys_post values(1, 'ceo', '董事长', 1, '0', 'admin', sysdate(), '', null, ''); +insert into sys_post values(2, 'se', '项目经理', 2, '0', 'admin', sysdate(), '', null, ''); +insert into sys_post values(3, 'hr', '人力资源', 3, '0', 'admin', sysdate(), '', null, ''); +insert into sys_post values(4, 'user', '普通员工', 4, '0', 'admin', sysdate(), '', null, ''); + + +-- ---------------------------- +-- 4、角色信息表 +-- ---------------------------- +drop table if exists sys_role; +create table sys_role ( + role_id bigint(20) not null auto_increment comment '角色ID', + role_name varchar(30) not null comment '角色名称', + role_key varchar(100) not null comment '角色权限字符串', + role_sort int(4) not null comment '显示顺序', + data_scope char(1) default '1' comment '数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限)', + menu_check_strictly tinyint(1) default 1 comment '菜单树选择项是否关联显示', + dept_check_strictly tinyint(1) default 1 comment '部门树选择项是否关联显示', + status char(1) not null comment '角色状态(0正常 1停用)', + del_flag char(1) default '0' comment '删除标志(0代表存在 2代表删除)', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + remark varchar(500) default null comment '备注', + primary key (role_id) +) engine=innodb auto_increment=100 comment = '角色信息表'; + +-- ---------------------------- +-- 初始化-角色信息表数据 +-- ---------------------------- +insert into sys_role values('1', '超级管理员', 'admin', 1, 1, 1, 1, '0', '0', 'admin', sysdate(), '', null, '超级管理员'); +insert into sys_role values('2', '普通角色', 'common', 2, 2, 1, 1, '0', '0', 'admin', sysdate(), '', null, '普通角色'); + + +-- ---------------------------- +-- 5、菜单权限表 +-- ---------------------------- +drop table if exists sys_menu; +create table sys_menu ( + menu_id bigint(20) not null auto_increment comment '菜单ID', + menu_name varchar(50) not null comment '菜单名称', + parent_id bigint(20) default 0 comment '父菜单ID', + order_num int(4) default 0 comment '显示顺序', + path varchar(200) default '' comment '路由地址', + component varchar(255) default null comment '组件路径', + query varchar(255) default null comment '路由参数', + route_name varchar(50) default '' comment '路由名称', + is_frame int(1) default 1 comment '是否为外链(0是 1否)', + is_cache int(1) default 0 comment '是否缓存(0缓存 1不缓存)', + menu_type char(1) default '' comment '菜单类型(M目录 C菜单 F按钮)', + visible char(1) default 0 comment '菜单状态(0显示 1隐藏)', + status char(1) default 0 comment '菜单状态(0正常 1停用)', + perms varchar(100) default null comment '权限标识', + icon varchar(100) default '#' comment '菜单图标', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + remark varchar(500) default '' comment '备注', + primary key (menu_id) +) engine=innodb auto_increment=2000 comment = '菜单权限表'; + +-- ---------------------------- +-- 初始化-菜单信息表数据 +-- ---------------------------- +-- 一级菜单 +insert into sys_menu values('1', '系统管理', '0', '1', 'system', null, '', '', 1, 0, 'M', '0', '0', '', 'system', 'admin', sysdate(), '', null, '系统管理目录'); +insert into sys_menu values('2', '系统监控', '0', '2', 'monitor', null, '', '', 1, 0, 'M', '0', '0', '', 'monitor', 'admin', sysdate(), '', null, '系统监控目录'); +insert into sys_menu values('3', '系统工具', '0', '3', 'tool', null, '', '', 1, 0, 'M', '0', '0', '', 'tool', 'admin', sysdate(), '', null, '系统工具目录'); +insert into sys_menu values('4', '若依官网', '0', '4', 'http://ruoyi.vip', null, '', '', 0, 0, 'M', '0', '0', '', 'guide', 'admin', sysdate(), '', null, '若依官网地址'); +-- 二级菜单 +insert into sys_menu values('100', '用户管理', '1', '1', 'user', 'system/user/index', '', '', 1, 0, 'C', '0', '0', 'system:user:list', 'user', 'admin', sysdate(), '', null, '用户管理菜单'); +insert into sys_menu values('101', '角色管理', '1', '2', 'role', 'system/role/index', '', '', 1, 0, 'C', '0', '0', 'system:role:list', 'peoples', 'admin', sysdate(), '', null, '角色管理菜单'); +insert into sys_menu values('102', '菜单管理', '1', '3', 'menu', 'system/menu/index', '', '', 1, 0, 'C', '0', '0', 'system:menu:list', 'tree-table', 'admin', sysdate(), '', null, '菜单管理菜单'); +insert into sys_menu values('103', '部门管理', '1', '4', 'dept', 'system/dept/index', '', '', 1, 0, 'C', '0', '0', 'system:dept:list', 'tree', 'admin', sysdate(), '', null, '部门管理菜单'); +insert into sys_menu values('104', '岗位管理', '1', '5', 'post', 'system/post/index', '', '', 1, 0, 'C', '0', '0', 'system:post:list', 'post', 'admin', sysdate(), '', null, '岗位管理菜单'); +insert into sys_menu values('105', '字典管理', '1', '6', 'dict', 'system/dict/index', '', '', 1, 0, 'C', '0', '0', 'system:dict:list', 'dict', 'admin', sysdate(), '', null, '字典管理菜单'); +insert into sys_menu values('106', '参数设置', '1', '7', 'config', 'system/config/index', '', '', 1, 0, 'C', '0', '0', 'system:config:list', 'edit', 'admin', sysdate(), '', null, '参数设置菜单'); +insert into sys_menu values('107', '通知公告', '1', '8', 'notice', 'system/notice/index', '', '', 1, 0, 'C', '0', '0', 'system:notice:list', 'message', 'admin', sysdate(), '', null, '通知公告菜单'); +insert into sys_menu values('108', '日志管理', '1', '9', 'log', '', '', '', 1, 0, 'M', '0', '0', '', 'log', 'admin', sysdate(), '', null, '日志管理菜单'); +insert into sys_menu values('109', '在线用户', '2', '1', 'online', 'monitor/online/index', '', '', 1, 0, 'C', '0', '0', 'monitor:online:list', 'online', 'admin', sysdate(), '', null, '在线用户菜单'); +insert into sys_menu values('110', '定时任务', '2', '2', 'job', 'monitor/job/index', '', '', 1, 0, 'C', '0', '0', 'monitor:job:list', 'job', 'admin', sysdate(), '', null, '定时任务菜单'); +insert into sys_menu values('111', '数据监控', '2', '3', 'druid', 'monitor/druid/index', '', '', 1, 0, 'C', '0', '0', 'monitor:druid:list', 'druid', 'admin', sysdate(), '', null, '数据监控菜单'); +insert into sys_menu values('112', '服务监控', '2', '4', 'server', 'monitor/server/index', '', '', 1, 0, 'C', '0', '0', 'monitor:server:list', 'server', 'admin', sysdate(), '', null, '服务监控菜单'); +insert into sys_menu values('113', '缓存监控', '2', '5', 'cache', 'monitor/cache/index', '', '', 1, 0, 'C', '0', '0', 'monitor:cache:list', 'redis', 'admin', sysdate(), '', null, '缓存监控菜单'); +insert into sys_menu values('114', '缓存列表', '2', '6', 'cacheList', 'monitor/cache/list', '', '', 1, 0, 'C', '0', '0', 'monitor:cache:list', 'redis-list', 'admin', sysdate(), '', null, '缓存列表菜单'); +insert into sys_menu values('115', '表单构建', '3', '1', 'build', 'tool/build/index', '', '', 1, 0, 'C', '0', '0', 'tool:build:list', 'build', 'admin', sysdate(), '', null, '表单构建菜单'); +insert into sys_menu values('116', '代码生成', '3', '2', 'gen', 'tool/gen/index', '', '', 1, 0, 'C', '0', '0', 'tool:gen:list', 'code', 'admin', sysdate(), '', null, '代码生成菜单'); +insert into sys_menu values('117', '系统接口', '3', '3', 'swagger', 'tool/swagger/index', '', '', 1, 0, 'C', '0', '0', 'tool:swagger:list', 'swagger', 'admin', sysdate(), '', null, '系统接口菜单'); +-- 三级菜单 +insert into sys_menu values('500', '操作日志', '108', '1', 'operlog', 'monitor/operlog/index', '', '', 1, 0, 'C', '0', '0', 'monitor:operlog:list', 'form', 'admin', sysdate(), '', null, '操作日志菜单'); +insert into sys_menu values('501', '登录日志', '108', '2', 'logininfor', 'monitor/logininfor/index', '', '', 1, 0, 'C', '0', '0', 'monitor:logininfor:list', 'logininfor', 'admin', sysdate(), '', null, '登录日志菜单'); +-- 用户管理按钮 +insert into sys_menu values('1000', '用户查询', '100', '1', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1001', '用户新增', '100', '2', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:add', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1002', '用户修改', '100', '3', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:edit', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1003', '用户删除', '100', '4', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:remove', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1004', '用户导出', '100', '5', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:export', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1005', '用户导入', '100', '6', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:import', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1006', '重置密码', '100', '7', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:resetPwd', '#', 'admin', sysdate(), '', null, ''); +-- 角色管理按钮 +insert into sys_menu values('1007', '角色查询', '101', '1', '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1008', '角色新增', '101', '2', '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:add', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1009', '角色修改', '101', '3', '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:edit', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1010', '角色删除', '101', '4', '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:remove', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1011', '角色导出', '101', '5', '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:export', '#', 'admin', sysdate(), '', null, ''); +-- 菜单管理按钮 +insert into sys_menu values('1012', '菜单查询', '102', '1', '', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1013', '菜单新增', '102', '2', '', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:add', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1014', '菜单修改', '102', '3', '', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:edit', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1015', '菜单删除', '102', '4', '', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:remove', '#', 'admin', sysdate(), '', null, ''); +-- 部门管理按钮 +insert into sys_menu values('1016', '部门查询', '103', '1', '', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1017', '部门新增', '103', '2', '', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:add', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1018', '部门修改', '103', '3', '', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:edit', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1019', '部门删除', '103', '4', '', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:remove', '#', 'admin', sysdate(), '', null, ''); +-- 岗位管理按钮 +insert into sys_menu values('1020', '岗位查询', '104', '1', '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1021', '岗位新增', '104', '2', '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:add', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1022', '岗位修改', '104', '3', '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:edit', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1023', '岗位删除', '104', '4', '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:remove', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1024', '岗位导出', '104', '5', '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:export', '#', 'admin', sysdate(), '', null, ''); +-- 字典管理按钮 +insert into sys_menu values('1025', '字典查询', '105', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1026', '字典新增', '105', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:add', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1027', '字典修改', '105', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:edit', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1028', '字典删除', '105', '4', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:remove', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1029', '字典导出', '105', '5', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:export', '#', 'admin', sysdate(), '', null, ''); +-- 参数设置按钮 +insert into sys_menu values('1030', '参数查询', '106', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1031', '参数新增', '106', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:add', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1032', '参数修改', '106', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:edit', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1033', '参数删除', '106', '4', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:remove', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1034', '参数导出', '106', '5', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:export', '#', 'admin', sysdate(), '', null, ''); +-- 通知公告按钮 +insert into sys_menu values('1035', '公告查询', '107', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:notice:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1036', '公告新增', '107', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:notice:add', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1037', '公告修改', '107', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:notice:edit', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1038', '公告删除', '107', '4', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:notice:remove', '#', 'admin', sysdate(), '', null, ''); +-- 操作日志按钮 +insert into sys_menu values('1039', '操作查询', '500', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1040', '操作删除', '500', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:remove', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1041', '日志导出', '500', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:export', '#', 'admin', sysdate(), '', null, ''); +-- 登录日志按钮 +insert into sys_menu values('1042', '登录查询', '501', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1043', '登录删除', '501', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:remove', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1044', '日志导出', '501', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:export', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1045', '账户解锁', '501', '4', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:unlock', '#', 'admin', sysdate(), '', null, ''); +-- 在线用户按钮 +insert into sys_menu values('1046', '在线查询', '109', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:online:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1047', '批量强退', '109', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:online:batchLogout', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1048', '单条强退', '109', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:online:forceLogout', '#', 'admin', sysdate(), '', null, ''); +-- 定时任务按钮 +insert into sys_menu values('1049', '任务查询', '110', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1050', '任务新增', '110', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:add', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1051', '任务修改', '110', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:edit', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1052', '任务删除', '110', '4', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:remove', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1053', '状态修改', '110', '5', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:changeStatus', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1054', '任务导出', '110', '6', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:export', '#', 'admin', sysdate(), '', null, ''); +-- 代码生成按钮 +insert into sys_menu values('1055', '生成查询', '116', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:query', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1056', '生成修改', '116', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:edit', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1057', '生成删除', '116', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:remove', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1058', '导入代码', '116', '4', '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:import', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1059', '预览代码', '116', '5', '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:preview', '#', 'admin', sysdate(), '', null, ''); +insert into sys_menu values('1060', '生成代码', '116', '6', '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:code', '#', 'admin', sysdate(), '', null, ''); + + +-- ---------------------------- +-- 6、用户和角色关联表 用户N-1角色 +-- ---------------------------- +drop table if exists sys_user_role; +create table sys_user_role ( + user_id bigint(20) not null comment '用户ID', + role_id bigint(20) not null comment '角色ID', + primary key(user_id, role_id) +) engine=innodb comment = '用户和角色关联表'; + +-- ---------------------------- +-- 初始化-用户和角色关联表数据 +-- ---------------------------- +insert into sys_user_role values ('1', '1'); +insert into sys_user_role values ('2', '2'); + + +-- ---------------------------- +-- 7、角色和菜单关联表 角色1-N菜单 +-- ---------------------------- +drop table if exists sys_role_menu; +create table sys_role_menu ( + role_id bigint(20) not null comment '角色ID', + menu_id bigint(20) not null comment '菜单ID', + primary key(role_id, menu_id) +) engine=innodb comment = '角色和菜单关联表'; + +-- ---------------------------- +-- 初始化-角色和菜单关联表数据 +-- ---------------------------- +insert into sys_role_menu values ('2', '1'); +insert into sys_role_menu values ('2', '2'); +insert into sys_role_menu values ('2', '3'); +insert into sys_role_menu values ('2', '4'); +insert into sys_role_menu values ('2', '100'); +insert into sys_role_menu values ('2', '101'); +insert into sys_role_menu values ('2', '102'); +insert into sys_role_menu values ('2', '103'); +insert into sys_role_menu values ('2', '104'); +insert into sys_role_menu values ('2', '105'); +insert into sys_role_menu values ('2', '106'); +insert into sys_role_menu values ('2', '107'); +insert into sys_role_menu values ('2', '108'); +insert into sys_role_menu values ('2', '109'); +insert into sys_role_menu values ('2', '110'); +insert into sys_role_menu values ('2', '111'); +insert into sys_role_menu values ('2', '112'); +insert into sys_role_menu values ('2', '113'); +insert into sys_role_menu values ('2', '114'); +insert into sys_role_menu values ('2', '115'); +insert into sys_role_menu values ('2', '116'); +insert into sys_role_menu values ('2', '117'); +insert into sys_role_menu values ('2', '500'); +insert into sys_role_menu values ('2', '501'); +insert into sys_role_menu values ('2', '1000'); +insert into sys_role_menu values ('2', '1001'); +insert into sys_role_menu values ('2', '1002'); +insert into sys_role_menu values ('2', '1003'); +insert into sys_role_menu values ('2', '1004'); +insert into sys_role_menu values ('2', '1005'); +insert into sys_role_menu values ('2', '1006'); +insert into sys_role_menu values ('2', '1007'); +insert into sys_role_menu values ('2', '1008'); +insert into sys_role_menu values ('2', '1009'); +insert into sys_role_menu values ('2', '1010'); +insert into sys_role_menu values ('2', '1011'); +insert into sys_role_menu values ('2', '1012'); +insert into sys_role_menu values ('2', '1013'); +insert into sys_role_menu values ('2', '1014'); +insert into sys_role_menu values ('2', '1015'); +insert into sys_role_menu values ('2', '1016'); +insert into sys_role_menu values ('2', '1017'); +insert into sys_role_menu values ('2', '1018'); +insert into sys_role_menu values ('2', '1019'); +insert into sys_role_menu values ('2', '1020'); +insert into sys_role_menu values ('2', '1021'); +insert into sys_role_menu values ('2', '1022'); +insert into sys_role_menu values ('2', '1023'); +insert into sys_role_menu values ('2', '1024'); +insert into sys_role_menu values ('2', '1025'); +insert into sys_role_menu values ('2', '1026'); +insert into sys_role_menu values ('2', '1027'); +insert into sys_role_menu values ('2', '1028'); +insert into sys_role_menu values ('2', '1029'); +insert into sys_role_menu values ('2', '1030'); +insert into sys_role_menu values ('2', '1031'); +insert into sys_role_menu values ('2', '1032'); +insert into sys_role_menu values ('2', '1033'); +insert into sys_role_menu values ('2', '1034'); +insert into sys_role_menu values ('2', '1035'); +insert into sys_role_menu values ('2', '1036'); +insert into sys_role_menu values ('2', '1037'); +insert into sys_role_menu values ('2', '1038'); +insert into sys_role_menu values ('2', '1039'); +insert into sys_role_menu values ('2', '1040'); +insert into sys_role_menu values ('2', '1041'); +insert into sys_role_menu values ('2', '1042'); +insert into sys_role_menu values ('2', '1043'); +insert into sys_role_menu values ('2', '1044'); +insert into sys_role_menu values ('2', '1045'); +insert into sys_role_menu values ('2', '1046'); +insert into sys_role_menu values ('2', '1047'); +insert into sys_role_menu values ('2', '1048'); +insert into sys_role_menu values ('2', '1049'); +insert into sys_role_menu values ('2', '1050'); +insert into sys_role_menu values ('2', '1051'); +insert into sys_role_menu values ('2', '1052'); +insert into sys_role_menu values ('2', '1053'); +insert into sys_role_menu values ('2', '1054'); +insert into sys_role_menu values ('2', '1055'); +insert into sys_role_menu values ('2', '1056'); +insert into sys_role_menu values ('2', '1057'); +insert into sys_role_menu values ('2', '1058'); +insert into sys_role_menu values ('2', '1059'); +insert into sys_role_menu values ('2', '1060'); + +-- ---------------------------- +-- 8、角色和部门关联表 角色1-N部门 +-- ---------------------------- +drop table if exists sys_role_dept; +create table sys_role_dept ( + role_id bigint(20) not null comment '角色ID', + dept_id bigint(20) not null comment '部门ID', + primary key(role_id, dept_id) +) engine=innodb comment = '角色和部门关联表'; + +-- ---------------------------- +-- 初始化-角色和部门关联表数据 +-- ---------------------------- +insert into sys_role_dept values ('2', '100'); +insert into sys_role_dept values ('2', '101'); +insert into sys_role_dept values ('2', '105'); + + +-- ---------------------------- +-- 9、用户与岗位关联表 用户1-N岗位 +-- ---------------------------- +drop table if exists sys_user_post; +create table sys_user_post +( + user_id bigint(20) not null comment '用户ID', + post_id bigint(20) not null comment '岗位ID', + primary key (user_id, post_id) +) engine=innodb comment = '用户与岗位关联表'; + +-- ---------------------------- +-- 初始化-用户与岗位关联表数据 +-- ---------------------------- +insert into sys_user_post values ('1', '1'); +insert into sys_user_post values ('2', '2'); + + +-- ---------------------------- +-- 10、操作日志记录 +-- ---------------------------- +drop table if exists sys_oper_log; +create table sys_oper_log ( + oper_id bigint(20) not null auto_increment comment '日志主键', + title varchar(50) default '' comment '模块标题', + business_type int(2) default 0 comment '业务类型(0其它 1新增 2修改 3删除)', + method varchar(200) default '' comment '方法名称', + request_method varchar(10) default '' comment '请求方式', + operator_type int(1) default 0 comment '操作类别(0其它 1后台用户 2手机端用户)', + oper_name varchar(50) default '' comment '操作人员', + dept_name varchar(50) default '' comment '部门名称', + oper_url varchar(255) default '' comment '请求URL', + oper_ip varchar(128) default '' comment '主机地址', + oper_location varchar(255) default '' comment '操作地点', + oper_param varchar(2000) default '' comment '请求参数', + json_result varchar(2000) default '' comment '返回参数', + status int(1) default 0 comment '操作状态(0正常 1异常)', + error_msg varchar(2000) default '' comment '错误消息', + oper_time datetime comment '操作时间', + cost_time bigint(20) default 0 comment '消耗时间', + primary key (oper_id), + key idx_sys_oper_log_bt (business_type), + key idx_sys_oper_log_s (status), + key idx_sys_oper_log_ot (oper_time) +) engine=innodb auto_increment=100 comment = '操作日志记录'; + + +-- ---------------------------- +-- 11、字典类型表 +-- ---------------------------- +drop table if exists sys_dict_type; +create table sys_dict_type +( + dict_id bigint(20) not null auto_increment comment '字典主键', + dict_name varchar(100) default '' comment '字典名称', + dict_type varchar(100) default '' comment '字典类型', + status char(1) default '0' comment '状态(0正常 1停用)', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + remark varchar(500) default null comment '备注', + primary key (dict_id), + unique (dict_type) +) engine=innodb auto_increment=100 comment = '字典类型表'; + +insert into sys_dict_type values(1, '用户性别', 'sys_user_sex', '0', 'admin', sysdate(), '', null, '用户性别列表'); +insert into sys_dict_type values(2, '菜单状态', 'sys_show_hide', '0', 'admin', sysdate(), '', null, '菜单状态列表'); +insert into sys_dict_type values(3, '系统开关', 'sys_normal_disable', '0', 'admin', sysdate(), '', null, '系统开关列表'); +insert into sys_dict_type values(4, '任务状态', 'sys_job_status', '0', 'admin', sysdate(), '', null, '任务状态列表'); +insert into sys_dict_type values(5, '任务分组', 'sys_job_group', '0', 'admin', sysdate(), '', null, '任务分组列表'); +insert into sys_dict_type values(6, '系统是否', 'sys_yes_no', '0', 'admin', sysdate(), '', null, '系统是否列表'); +insert into sys_dict_type values(7, '通知类型', 'sys_notice_type', '0', 'admin', sysdate(), '', null, '通知类型列表'); +insert into sys_dict_type values(8, '通知状态', 'sys_notice_status', '0', 'admin', sysdate(), '', null, '通知状态列表'); +insert into sys_dict_type values(9, '操作类型', 'sys_oper_type', '0', 'admin', sysdate(), '', null, '操作类型列表'); +insert into sys_dict_type values(10, '系统状态', 'sys_common_status', '0', 'admin', sysdate(), '', null, '登录状态列表'); + + +-- ---------------------------- +-- 12、字典数据表 +-- ---------------------------- +drop table if exists sys_dict_data; +create table sys_dict_data +( + dict_code bigint(20) not null auto_increment comment '字典编码', + dict_sort int(4) default 0 comment '字典排序', + dict_label varchar(100) default '' comment '字典标签', + dict_value varchar(100) default '' comment '字典键值', + dict_type varchar(100) default '' comment '字典类型', + css_class varchar(100) default null comment '样式属性(其他样式扩展)', + list_class varchar(100) default null comment '表格回显样式', + is_default char(1) default 'N' comment '是否默认(Y是 N否)', + status char(1) default '0' comment '状态(0正常 1停用)', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + remark varchar(500) default null comment '备注', + primary key (dict_code) +) engine=innodb auto_increment=100 comment = '字典数据表'; + +insert into sys_dict_data values(1, 1, '男', '0', 'sys_user_sex', '', '', 'Y', '0', 'admin', sysdate(), '', null, '性别男'); +insert into sys_dict_data values(2, 2, '女', '1', 'sys_user_sex', '', '', 'N', '0', 'admin', sysdate(), '', null, '性别女'); +insert into sys_dict_data values(3, 3, '未知', '2', 'sys_user_sex', '', '', 'N', '0', 'admin', sysdate(), '', null, '性别未知'); +insert into sys_dict_data values(4, 1, '显示', '0', 'sys_show_hide', '', 'primary', 'Y', '0', 'admin', sysdate(), '', null, '显示菜单'); +insert into sys_dict_data values(5, 2, '隐藏', '1', 'sys_show_hide', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '隐藏菜单'); +insert into sys_dict_data values(6, 1, '正常', '0', 'sys_normal_disable', '', 'primary', 'Y', '0', 'admin', sysdate(), '', null, '正常状态'); +insert into sys_dict_data values(7, 2, '停用', '1', 'sys_normal_disable', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '停用状态'); +insert into sys_dict_data values(8, 1, '正常', '0', 'sys_job_status', '', 'primary', 'Y', '0', 'admin', sysdate(), '', null, '正常状态'); +insert into sys_dict_data values(9, 2, '暂停', '1', 'sys_job_status', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '停用状态'); +insert into sys_dict_data values(10, 1, '默认', 'DEFAULT', 'sys_job_group', '', '', 'Y', '0', 'admin', sysdate(), '', null, '默认分组'); +insert into sys_dict_data values(11, 2, '系统', 'SYSTEM', 'sys_job_group', '', '', 'N', '0', 'admin', sysdate(), '', null, '系统分组'); +insert into sys_dict_data values(12, 1, '是', 'Y', 'sys_yes_no', '', 'primary', 'Y', '0', 'admin', sysdate(), '', null, '系统默认是'); +insert into sys_dict_data values(13, 2, '否', 'N', 'sys_yes_no', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '系统默认否'); +insert into sys_dict_data values(14, 1, '通知', '1', 'sys_notice_type', '', 'warning', 'Y', '0', 'admin', sysdate(), '', null, '通知'); +insert into sys_dict_data values(15, 2, '公告', '2', 'sys_notice_type', '', 'success', 'N', '0', 'admin', sysdate(), '', null, '公告'); +insert into sys_dict_data values(16, 1, '正常', '0', 'sys_notice_status', '', 'primary', 'Y', '0', 'admin', sysdate(), '', null, '正常状态'); +insert into sys_dict_data values(17, 2, '关闭', '1', 'sys_notice_status', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '关闭状态'); +insert into sys_dict_data values(18, 99, '其他', '0', 'sys_oper_type', '', 'info', 'N', '0', 'admin', sysdate(), '', null, '其他操作'); +insert into sys_dict_data values(19, 1, '新增', '1', 'sys_oper_type', '', 'info', 'N', '0', 'admin', sysdate(), '', null, '新增操作'); +insert into sys_dict_data values(20, 2, '修改', '2', 'sys_oper_type', '', 'info', 'N', '0', 'admin', sysdate(), '', null, '修改操作'); +insert into sys_dict_data values(21, 3, '删除', '3', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '删除操作'); +insert into sys_dict_data values(22, 4, '授权', '4', 'sys_oper_type', '', 'primary', 'N', '0', 'admin', sysdate(), '', null, '授权操作'); +insert into sys_dict_data values(23, 5, '导出', '5', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', sysdate(), '', null, '导出操作'); +insert into sys_dict_data values(24, 6, '导入', '6', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', sysdate(), '', null, '导入操作'); +insert into sys_dict_data values(25, 7, '强退', '7', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '强退操作'); +insert into sys_dict_data values(26, 8, '生成代码', '8', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', sysdate(), '', null, '生成操作'); +insert into sys_dict_data values(27, 9, '清空数据', '9', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '清空操作'); +insert into sys_dict_data values(28, 1, '成功', '0', 'sys_common_status', '', 'primary', 'N', '0', 'admin', sysdate(), '', null, '正常状态'); +insert into sys_dict_data values(29, 2, '失败', '1', 'sys_common_status', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '停用状态'); + + +-- ---------------------------- +-- 13、参数配置表 +-- ---------------------------- +drop table if exists sys_config; +create table sys_config ( + config_id int(5) not null auto_increment comment '参数主键', + config_name varchar(100) default '' comment '参数名称', + config_key varchar(100) default '' comment '参数键名', + config_value varchar(500) default '' comment '参数键值', + config_type char(1) default 'N' comment '系统内置(Y是 N否)', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + remark varchar(500) default null comment '备注', + primary key (config_id) +) engine=innodb auto_increment=100 comment = '参数配置表'; + +insert into sys_config values(1, '主框架页-默认皮肤样式名称', 'sys.index.skinName', 'skin-blue', 'Y', 'admin', sysdate(), '', null, '蓝色 skin-blue、绿色 skin-green、紫色 skin-purple、红色 skin-red、黄色 skin-yellow' ); +insert into sys_config values(2, '用户管理-账号初始密码', 'sys.user.initPassword', '123456', 'Y', 'admin', sysdate(), '', null, '初始化密码 123456' ); +insert into sys_config values(3, '主框架页-侧边栏主题', 'sys.index.sideTheme', 'theme-dark', 'Y', 'admin', sysdate(), '', null, '深色主题theme-dark,浅色主题theme-light' ); +insert into sys_config values(4, '账号自助-验证码开关', 'sys.account.captchaEnabled', 'true', 'Y', 'admin', sysdate(), '', null, '是否开启验证码功能(true开启,false关闭)'); +insert into sys_config values(5, '账号自助-是否开启用户注册功能', 'sys.account.registerUser', 'false', 'Y', 'admin', sysdate(), '', null, '是否开启注册用户功能(true开启,false关闭)'); +insert into sys_config values(6, '用户登录-黑名单列表', 'sys.login.blackIPList', '', 'Y', 'admin', sysdate(), '', null, '设置登录IP黑名单限制,多个匹配项以;分隔,支持匹配(*通配、网段)'); + + +-- ---------------------------- +-- 14、系统访问记录 +-- ---------------------------- +drop table if exists sys_logininfor; +create table sys_logininfor ( + info_id bigint(20) not null auto_increment comment '访问ID', + user_name varchar(50) default '' comment '用户账号', + ipaddr varchar(128) default '' comment '登录IP地址', + login_location varchar(255) default '' comment '登录地点', + browser varchar(50) default '' comment '浏览器类型', + os varchar(50) default '' comment '操作系统', + status char(1) default '0' comment '登录状态(0成功 1失败)', + msg varchar(255) default '' comment '提示消息', + login_time datetime comment '访问时间', + primary key (info_id), + key idx_sys_logininfor_s (status), + key idx_sys_logininfor_lt (login_time) +) engine=innodb auto_increment=100 comment = '系统访问记录'; + + +-- ---------------------------- +-- 15、定时任务调度表 +-- ---------------------------- +drop table if exists sys_job; +create table sys_job ( + job_id bigint(20) not null auto_increment comment '任务ID', + job_name varchar(64) default '' comment '任务名称', + job_group varchar(64) default 'DEFAULT' comment '任务组名', + invoke_target varchar(500) not null comment '调用目标字符串', + cron_expression varchar(255) default '' comment 'cron执行表达式', + misfire_policy varchar(20) default '3' comment '计划执行错误策略(1立即执行 2执行一次 3放弃执行)', + concurrent char(1) default '1' comment '是否并发执行(0允许 1禁止)', + status char(1) default '0' comment '状态(0正常 1暂停)', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + remark varchar(500) default '' comment '备注信息', + primary key (job_id, job_name, job_group) +) engine=innodb auto_increment=100 comment = '定时任务调度表'; + +insert into sys_job values(1, '系统默认(无参)', 'DEFAULT', 'ryTask.ryNoParams', '0/10 * * * * ?', '3', '1', '1', 'admin', sysdate(), '', null, ''); +insert into sys_job values(2, '系统默认(有参)', 'DEFAULT', 'ryTask.ryParams(\'ry\')', '0/15 * * * * ?', '3', '1', '1', 'admin', sysdate(), '', null, ''); +insert into sys_job values(3, '系统默认(多参)', 'DEFAULT', 'ryTask.ryMultipleParams(\'ry\', true, 2000L, 316.50D, 100)', '0/20 * * * * ?', '3', '1', '1', 'admin', sysdate(), '', null, ''); + + +-- ---------------------------- +-- 16、定时任务调度日志表 +-- ---------------------------- +drop table if exists sys_job_log; +create table sys_job_log ( + job_log_id bigint(20) not null auto_increment comment '任务日志ID', + job_name varchar(64) not null comment '任务名称', + job_group varchar(64) not null comment '任务组名', + invoke_target varchar(500) not null comment '调用目标字符串', + job_message varchar(500) comment '日志信息', + status char(1) default '0' comment '执行状态(0正常 1失败)', + exception_info varchar(2000) default '' comment '异常信息', + create_time datetime comment '创建时间', + primary key (job_log_id) +) engine=innodb comment = '定时任务调度日志表'; + + +-- ---------------------------- +-- 17、通知公告表 +-- ---------------------------- +drop table if exists sys_notice; +create table sys_notice ( + notice_id int(4) not null auto_increment comment '公告ID', + notice_title varchar(50) not null comment '公告标题', + notice_type char(1) not null comment '公告类型(1通知 2公告)', + notice_content longblob default null comment '公告内容', + status char(1) default '0' comment '公告状态(0正常 1关闭)', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + remark varchar(255) default null comment '备注', + primary key (notice_id) +) engine=innodb auto_increment=10 comment = '通知公告表'; + +-- ---------------------------- +-- 初始化-公告信息表数据 +-- ---------------------------- +insert into sys_notice values('1', '温馨提醒:2018-07-01 若依新版本发布啦', '2', '新版本内容', '0', 'admin', sysdate(), '', null, '管理员'); +insert into sys_notice values('2', '维护通知:2018-07-01 若依系统凌晨维护', '1', '维护内容', '0', 'admin', sysdate(), '', null, '管理员'); + + +-- ---------------------------- +-- 18、代码生成业务表 +-- ---------------------------- +drop table if exists gen_table; +create table gen_table ( + table_id bigint(20) not null auto_increment comment '编号', + table_name varchar(200) default '' comment '表名称', + table_comment varchar(500) default '' comment '表描述', + sub_table_name varchar(64) default null comment '关联子表的表名', + sub_table_fk_name varchar(64) default null comment '子表关联的外键名', + class_name varchar(100) default '' comment '实体类名称', + tpl_category varchar(200) default 'crud' comment '使用的模板(crud单表操作 tree树表操作)', + tpl_web_type varchar(30) default '' comment '前端模板类型(element-ui模版 element-plus模版)', + package_name varchar(100) comment '生成包路径', + module_name varchar(30) comment '生成模块名', + business_name varchar(30) comment '生成业务名', + function_name varchar(50) comment '生成功能名', + function_author varchar(50) comment '生成功能作者', + gen_type char(1) default '0' comment '生成代码方式(0zip压缩包 1自定义路径)', + gen_path varchar(200) default '/' comment '生成路径(不填默认项目路径)', + options varchar(1000) comment '其它生成选项', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + remark varchar(500) default null comment '备注', + primary key (table_id) +) engine=innodb auto_increment=1 comment = '代码生成业务表'; + + +-- ---------------------------- +-- 19、代码生成业务表字段 +-- ---------------------------- +drop table if exists gen_table_column; +create table gen_table_column ( + column_id bigint(20) not null auto_increment comment '编号', + table_id bigint(20) comment '归属表编号', + column_name varchar(200) comment '列名称', + column_comment varchar(500) comment '列描述', + column_type varchar(100) comment '列类型', + java_type varchar(500) comment 'JAVA类型', + java_field varchar(200) comment 'JAVA字段名', + is_pk char(1) comment '是否主键(1是)', + is_increment char(1) comment '是否自增(1是)', + is_required char(1) comment '是否必填(1是)', + is_insert char(1) comment '是否为插入字段(1是)', + is_edit char(1) comment '是否编辑字段(1是)', + is_list char(1) comment '是否列表字段(1是)', + is_query char(1) comment '是否查询字段(1是)', + query_type varchar(200) default 'EQ' comment '查询方式(等于、不等于、大于、小于、范围)', + html_type varchar(200) comment '显示类型(文本框、文本域、下拉框、复选框、单选框、日期控件)', + dict_type varchar(200) default '' comment '字典类型', + sort int comment '排序', + create_by varchar(64) default '' comment '创建者', + create_time datetime comment '创建时间', + update_by varchar(64) default '' comment '更新者', + update_time datetime comment '更新时间', + primary key (column_id) +) engine=innodb auto_increment=1 comment = '代码生成业务表字段'; \ No newline at end of file diff --git a/zzyl-admin/Dockerfile b/zzyl-admin/Dockerfile new file mode 100644 index 0000000..01095f0 --- /dev/null +++ b/zzyl-admin/Dockerfile @@ -0,0 +1,9 @@ +# 基础镜像 +FROM openjdk:11.0-jre-buster +# 设定时区 +ENV TZ=Asia/Shanghai +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone +# 拷贝jar包 +COPY zzyl-admin.jar /app.jar +# 入口 +ENTRYPOINT ["java", "-jar", "/app.jar"] diff --git a/zzyl-admin/deploy.sh b/zzyl-admin/deploy.sh new file mode 100644 index 0000000..b5b5f67 --- /dev/null +++ b/zzyl-admin/deploy.sh @@ -0,0 +1,29 @@ +#!/bin/bash +# 容器名称 +container_name=$1 +# 镜像名称 +image_name=$1 +# 镜像tag +image_tag=$2 + +# 判断容器是否存在 +if docker ps -a | grep $container_name | awk '{print $1}'; then + echo "容器 $container_name 存在" + if docker ps | grep $container_name | awk '{print $1}';then + echo "关闭正在运行的容器 $container_name" + docker stop `docker ps | grep $container_name | awk '{print $1}'` + else + echo "容器 $container_name 都已关闭" + fi + # 删除容器 + echo "删除容器 $container_name" + docker rm `docker ps -a | grep $container_name | awk '{print $1}'` +else + echo "容器 $container_name 不存在" +fi + +# 启动容器 +echo "启动容器 $container_name" +if [ $container_name = "zzyl-admin" ]; then + docker run -d --restart=always --name $container_name -v /usr/local/zzyl-admin/logs:/home/ruoyi/logs -p 9000:9000 $image_name:$image_tag +fi \ No newline at end of file diff --git a/zzyl-admin/pom.xml b/zzyl-admin/pom.xml new file mode 100644 index 0000000..11c28d5 --- /dev/null +++ b/zzyl-admin/pom.xml @@ -0,0 +1,115 @@ + + + + zzyl + com.zzyl + 3.8.8 + + 4.0.0 + jar + zzyl-admin + + + web服务入口 + + + + + + + + + + + + + + + mysql + mysql-connector-java + + + + + com.zzyl + zzyl-framework + + + + + com.zzyl + zzyl-quartz + + + + + com.zzyl + zzyl-generator + + + + + com.zzyl + zzyl-nursing-platform + + + + + com.zzyl + zzyl-oss + + + + org.springframework.boot + spring-boot-starter-test + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + 2.5.15 + + true + + + + + repackage + + + + + + org.apache.maven.plugins + maven-war-plugin + 3.1.0 + + false + ${project.artifactId} + + + + ${project.artifactId} + + + \ No newline at end of file diff --git a/zzyl-admin/src/main/java/com/zzyl/RuoYiApplication.java b/zzyl-admin/src/main/java/com/zzyl/RuoYiApplication.java new file mode 100644 index 0000000..26a35cc --- /dev/null +++ b/zzyl-admin/src/main/java/com/zzyl/RuoYiApplication.java @@ -0,0 +1,32 @@ +package com.zzyl; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.scheduling.annotation.EnableScheduling; + +/** + * 启动程序 + * + * @author ruoyi + */ +@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class }) +@EnableScheduling +public class RuoYiApplication +{ + public static void main(String[] args) + { + // System.setProperty("spring.devtools.restart.enabled", "false"); + SpringApplication.run(RuoYiApplication.class, args); + System.out.println("(♥◠‿◠)ノ゙ 若依启动成功 ლ(´ڡ`ლ)゙ \n" + + " .-------. ____ __ \n" + + " | _ _ \\ \\ \\ / / \n" + + " | ( ' ) | \\ _. / ' \n" + + " |(_ o _) / _( )_ .' \n" + + " | (_,_).' __ ___(_ o _)' \n" + + " | |\\ \\ | || |(_,_)' \n" + + " | | \\ `' /| `-' / \n" + + " | | \\ / \\ / \n" + + " ''-' `'-' `-..-' "); + } +} diff --git a/zzyl-admin/src/main/java/com/zzyl/RuoYiServletInitializer.java b/zzyl-admin/src/main/java/com/zzyl/RuoYiServletInitializer.java new file mode 100644 index 0000000..08b8a11 --- /dev/null +++ b/zzyl-admin/src/main/java/com/zzyl/RuoYiServletInitializer.java @@ -0,0 +1,18 @@ +package com.zzyl; + +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; + +/** + * web容器中进行部署 + * + * @author ruoyi + */ +public class RuoYiServletInitializer extends SpringBootServletInitializer +{ + @Override + protected SpringApplicationBuilder configure(SpringApplicationBuilder application) + { + return application.sources(RuoYiApplication.class); + } +} diff --git a/zzyl-admin/src/main/java/com/zzyl/web/controller/common/CaptchaController.java b/zzyl-admin/src/main/java/com/zzyl/web/controller/common/CaptchaController.java new file mode 100644 index 0000000..5eee3f8 --- /dev/null +++ b/zzyl-admin/src/main/java/com/zzyl/web/controller/common/CaptchaController.java @@ -0,0 +1,94 @@ +package com.zzyl.web.controller.common; + +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.util.concurrent.TimeUnit; +import javax.annotation.Resource; +import javax.imageio.ImageIO; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.util.FastByteArrayOutputStream; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; +import com.google.code.kaptcha.Producer; +import com.zzyl.common.config.RuoYiConfig; +import com.zzyl.common.constant.CacheConstants; +import com.zzyl.common.constant.Constants; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.core.redis.RedisCache; +import com.zzyl.common.utils.sign.Base64; +import com.zzyl.common.utils.uuid.IdUtils; +import com.zzyl.system.service.ISysConfigService; + +/** + * 验证码操作处理 + * + * @author ruoyi + */ +@RestController +public class CaptchaController +{ + @Resource(name = "captchaProducer") + private Producer captchaProducer; + + @Resource(name = "captchaProducerMath") + private Producer captchaProducerMath; + + @Autowired + private RedisCache redisCache; + + @Autowired + private ISysConfigService configService; + /** + * 生成验证码 + */ + @GetMapping("/captchaImage") + public AjaxResult getCode(HttpServletResponse response) throws IOException + { + AjaxResult ajax = AjaxResult.success(); + boolean captchaEnabled = configService.selectCaptchaEnabled(); + ajax.put("captchaEnabled", captchaEnabled); + if (!captchaEnabled) + { + return ajax; + } + + // 保存验证码信息 + String uuid = IdUtils.simpleUUID(); + String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid; + + String capStr = null, code = null; + BufferedImage image = null; + + // 生成验证码 + String captchaType = RuoYiConfig.getCaptchaType(); + if ("math".equals(captchaType)) + { + String capText = captchaProducerMath.createText(); + capStr = capText.substring(0, capText.lastIndexOf("@")); + code = capText.substring(capText.lastIndexOf("@") + 1); + image = captchaProducerMath.createImage(capStr); + } + else if ("char".equals(captchaType)) + { + capStr = code = captchaProducer.createText(); + image = captchaProducer.createImage(capStr); + } + + redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES); + // 转换流信息写出 + FastByteArrayOutputStream os = new FastByteArrayOutputStream(); + try + { + ImageIO.write(image, "jpg", os); + } + catch (IOException e) + { + return AjaxResult.error(e.getMessage()); + } + + ajax.put("uuid", uuid); + ajax.put("img", Base64.encode(os.toByteArray())); + return ajax; + } +} diff --git a/zzyl-admin/src/main/java/com/zzyl/web/controller/common/CommonController.java b/zzyl-admin/src/main/java/com/zzyl/web/controller/common/CommonController.java new file mode 100644 index 0000000..44c001c --- /dev/null +++ b/zzyl-admin/src/main/java/com/zzyl/web/controller/common/CommonController.java @@ -0,0 +1,170 @@ +package com.zzyl.web.controller.common; + +import com.zzyl.common.config.RuoYiConfig; +import com.zzyl.common.constant.Constants; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.common.utils.file.FileUploadUtils; +import com.zzyl.common.utils.file.FileUtils; +import com.zzyl.framework.config.ServerConfig; +import com.zzyl.oss.AliyunOssUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.ArrayList; +import java.util.List; + +/** + * 通用请求处理 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/common") +public class CommonController +{ + private static final Logger log = LoggerFactory.getLogger(CommonController.class); + + @Autowired + private ServerConfig serverConfig; + + @Autowired + private AliyunOssUtils aliyunOssUtils; + + private static final String FILE_DELIMETER = ","; + + /** + * 通用下载请求 + * + * @param fileName 文件名称 + * @param delete 是否删除 + */ + @GetMapping("/download") + public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request) + { + try + { + if (!FileUtils.checkAllowDownload(fileName)) + { + throw new Exception(StringUtils.format("文件名称({})非法,不允许下载。 ", fileName)); + } + String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1); + String filePath = RuoYiConfig.getDownloadPath() + fileName; + + response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); + FileUtils.setAttachmentResponseHeader(response, realFileName); + FileUtils.writeBytes(filePath, response.getOutputStream()); + if (delete) + { + FileUtils.deleteFile(filePath); + } + } + catch (Exception e) + { + log.error("下载文件失败", e); + } + } + + /** + * 通用上传请求(单个) + */ + @PostMapping("/upload") + public AjaxResult uploadFile(MultipartFile file) throws Exception + { + try + { + // 上传文件路径 + String filePath = RuoYiConfig.getUploadPath(); + // 上传并返回新文件名称 +// String fileName = FileUploadUtils.upload(filePath, file); + String url = aliyunOssUtils.uploadFile(file); + +// String url = serverConfig.getUrl() + fileName; + AjaxResult ajax = AjaxResult.success(); + ajax.put("url", url); + ajax.put("fileName", url); + ajax.put("newFileName", FileUtils.getName(url)); + ajax.put("originalFilename", file.getOriginalFilename()); + return ajax; + } + catch (Exception e) + { + return AjaxResult.error(e.getMessage()); + } + } + + /** + * 通用上传请求(多个) + */ + @PostMapping("/uploads") + public AjaxResult uploadFiles(List files) throws Exception + { + try + { + // 上传文件路径 + String filePath = RuoYiConfig.getUploadPath(); + List urls = new ArrayList(); + List fileNames = new ArrayList(); + List newFileNames = new ArrayList(); + List originalFilenames = new ArrayList(); + for (MultipartFile file : files) + { + // 上传并返回新文件名称 + String fileName = FileUploadUtils.upload(filePath, file); + String url = serverConfig.getUrl() + fileName; + urls.add(url); + fileNames.add(fileName); + newFileNames.add(FileUtils.getName(fileName)); + originalFilenames.add(file.getOriginalFilename()); + } + AjaxResult ajax = AjaxResult.success(); + ajax.put("urls", StringUtils.join(urls, FILE_DELIMETER)); + ajax.put("fileNames", StringUtils.join(fileNames, FILE_DELIMETER)); + ajax.put("newFileNames", StringUtils.join(newFileNames, FILE_DELIMETER)); + ajax.put("originalFilenames", StringUtils.join(originalFilenames, FILE_DELIMETER)); + return ajax; + } + catch (Exception e) + { + return AjaxResult.error(e.getMessage()); + } + } + + /** + * 本地资源通用下载 + */ + @GetMapping("/download/resource") + public void resourceDownload(String resource, HttpServletRequest request, HttpServletResponse response) + throws Exception + { + try + { + if (!FileUtils.checkAllowDownload(resource)) + { + throw new Exception(StringUtils.format("资源文件({})非法,不允许下载。 ", resource)); + } + // 本地资源路径 + String localPath = RuoYiConfig.getProfile(); + // 数据库资源地址 + String downloadPath = localPath + StringUtils.substringAfter(resource, Constants.RESOURCE_PREFIX); + // 下载名称 + String downloadName = StringUtils.substringAfterLast(downloadPath, "/"); + response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); + FileUtils.setAttachmentResponseHeader(response, downloadName); + FileUtils.writeBytes(downloadPath, response.getOutputStream()); + } + catch (Exception e) + { + log.error("下载文件失败", e); + } + } +} diff --git a/zzyl-admin/src/main/java/com/zzyl/web/controller/monitor/CacheController.java b/zzyl-admin/src/main/java/com/zzyl/web/controller/monitor/CacheController.java new file mode 100644 index 0000000..ce08d17 --- /dev/null +++ b/zzyl-admin/src/main/java/com/zzyl/web/controller/monitor/CacheController.java @@ -0,0 +1,121 @@ +package com.zzyl.web.controller.monitor; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.TreeSet; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisCallback; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.zzyl.common.constant.CacheConstants; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.system.domain.SysCache; + +/** + * 缓存监控 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/monitor/cache") +public class CacheController +{ + @Autowired + private RedisTemplate redisTemplate; + + private final static List caches = new ArrayList(); + { + caches.add(new SysCache(CacheConstants.LOGIN_TOKEN_KEY, "用户信息")); + caches.add(new SysCache(CacheConstants.SYS_CONFIG_KEY, "配置信息")); + caches.add(new SysCache(CacheConstants.SYS_DICT_KEY, "数据字典")); + caches.add(new SysCache(CacheConstants.CAPTCHA_CODE_KEY, "验证码")); + caches.add(new SysCache(CacheConstants.REPEAT_SUBMIT_KEY, "防重提交")); + caches.add(new SysCache(CacheConstants.RATE_LIMIT_KEY, "限流处理")); + caches.add(new SysCache(CacheConstants.PWD_ERR_CNT_KEY, "密码错误次数")); + } + + @PreAuthorize("@ss.hasPermi('monitor:cache:list')") + @GetMapping() + public AjaxResult getInfo() throws Exception + { + Properties info = (Properties) redisTemplate.execute((RedisCallback) connection -> connection.info()); + Properties commandStats = (Properties) redisTemplate.execute((RedisCallback) connection -> connection.info("commandstats")); + Object dbSize = redisTemplate.execute((RedisCallback) connection -> connection.dbSize()); + + Map result = new HashMap<>(3); + result.put("info", info); + result.put("dbSize", dbSize); + + List> pieList = new ArrayList<>(); + commandStats.stringPropertyNames().forEach(key -> { + Map data = new HashMap<>(2); + String property = commandStats.getProperty(key); + data.put("name", StringUtils.removeStart(key, "cmdstat_")); + data.put("value", StringUtils.substringBetween(property, "calls=", ",usec")); + pieList.add(data); + }); + result.put("commandStats", pieList); + return AjaxResult.success(result); + } + + @PreAuthorize("@ss.hasPermi('monitor:cache:list')") + @GetMapping("/getNames") + public AjaxResult cache() + { + return AjaxResult.success(caches); + } + + @PreAuthorize("@ss.hasPermi('monitor:cache:list')") + @GetMapping("/getKeys/{cacheName}") + public AjaxResult getCacheKeys(@PathVariable String cacheName) + { + Set cacheKeys = redisTemplate.keys(cacheName + "*"); + return AjaxResult.success(new TreeSet<>(cacheKeys)); + } + + @PreAuthorize("@ss.hasPermi('monitor:cache:list')") + @GetMapping("/getValue/{cacheName}/{cacheKey}") + public AjaxResult getCacheValue(@PathVariable String cacheName, @PathVariable String cacheKey) + { + String cacheValue = redisTemplate.opsForValue().get(cacheKey); + SysCache sysCache = new SysCache(cacheName, cacheKey, cacheValue); + return AjaxResult.success(sysCache); + } + + @PreAuthorize("@ss.hasPermi('monitor:cache:list')") + @DeleteMapping("/clearCacheName/{cacheName}") + public AjaxResult clearCacheName(@PathVariable String cacheName) + { + Collection cacheKeys = redisTemplate.keys(cacheName + "*"); + redisTemplate.delete(cacheKeys); + return AjaxResult.success(); + } + + @PreAuthorize("@ss.hasPermi('monitor:cache:list')") + @DeleteMapping("/clearCacheKey/{cacheKey}") + public AjaxResult clearCacheKey(@PathVariable String cacheKey) + { + redisTemplate.delete(cacheKey); + return AjaxResult.success(); + } + + @PreAuthorize("@ss.hasPermi('monitor:cache:list')") + @DeleteMapping("/clearCacheAll") + public AjaxResult clearCacheAll() + { + Collection cacheKeys = redisTemplate.keys("*"); + redisTemplate.delete(cacheKeys); + return AjaxResult.success(); + } +} diff --git a/zzyl-admin/src/main/java/com/zzyl/web/controller/monitor/ServerController.java b/zzyl-admin/src/main/java/com/zzyl/web/controller/monitor/ServerController.java new file mode 100644 index 0000000..b907184 --- /dev/null +++ b/zzyl-admin/src/main/java/com/zzyl/web/controller/monitor/ServerController.java @@ -0,0 +1,27 @@ +package com.zzyl.web.controller.monitor; + +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.framework.web.domain.Server; + +/** + * 服务器监控 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/monitor/server") +public class ServerController +{ + @PreAuthorize("@ss.hasPermi('monitor:server:list')") + @GetMapping() + public AjaxResult getInfo() throws Exception + { + Server server = new Server(); + server.copyTo(); + return AjaxResult.success(server); + } +} diff --git a/zzyl-admin/src/main/java/com/zzyl/web/controller/monitor/SysLogininforController.java b/zzyl-admin/src/main/java/com/zzyl/web/controller/monitor/SysLogininforController.java new file mode 100644 index 0000000..79b7571 --- /dev/null +++ b/zzyl-admin/src/main/java/com/zzyl/web/controller/monitor/SysLogininforController.java @@ -0,0 +1,82 @@ +package com.zzyl.web.controller.monitor; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.zzyl.common.annotation.Log; +import com.zzyl.common.core.controller.BaseController; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.core.page.TableDataInfo; +import com.zzyl.common.enums.BusinessType; +import com.zzyl.common.utils.poi.ExcelUtil; +import com.zzyl.framework.web.service.SysPasswordService; +import com.zzyl.system.domain.SysLogininfor; +import com.zzyl.system.service.ISysLogininforService; + +/** + * 系统访问记录 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/monitor/logininfor") +public class SysLogininforController extends BaseController +{ + @Autowired + private ISysLogininforService logininforService; + + @Autowired + private SysPasswordService passwordService; + + @PreAuthorize("@ss.hasPermi('monitor:logininfor:list')") + @GetMapping("/list") + public TableDataInfo list(SysLogininfor logininfor) + { + startPage(); + List list = logininforService.selectLogininforList(logininfor); + return getDataTable(list); + } + + @Log(title = "登录日志", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('monitor:logininfor:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysLogininfor logininfor) + { + List list = logininforService.selectLogininforList(logininfor); + ExcelUtil util = new ExcelUtil(SysLogininfor.class); + util.exportExcel(response, list, "登录日志"); + } + + @PreAuthorize("@ss.hasPermi('monitor:logininfor:remove')") + @Log(title = "登录日志", businessType = BusinessType.DELETE) + @DeleteMapping("/{infoIds}") + public AjaxResult remove(@PathVariable Long[] infoIds) + { + return toAjax(logininforService.deleteLogininforByIds(infoIds)); + } + + @PreAuthorize("@ss.hasPermi('monitor:logininfor:remove')") + @Log(title = "登录日志", businessType = BusinessType.CLEAN) + @DeleteMapping("/clean") + public AjaxResult clean() + { + logininforService.cleanLogininfor(); + return success(); + } + + @PreAuthorize("@ss.hasPermi('monitor:logininfor:unlock')") + @Log(title = "账户解锁", businessType = BusinessType.OTHER) + @GetMapping("/unlock/{userName}") + public AjaxResult unlock(@PathVariable("userName") String userName) + { + passwordService.clearLoginRecordCache(userName); + return success(); + } +} diff --git a/zzyl-admin/src/main/java/com/zzyl/web/controller/monitor/SysOperlogController.java b/zzyl-admin/src/main/java/com/zzyl/web/controller/monitor/SysOperlogController.java new file mode 100644 index 0000000..db54272 --- /dev/null +++ b/zzyl-admin/src/main/java/com/zzyl/web/controller/monitor/SysOperlogController.java @@ -0,0 +1,69 @@ +package com.zzyl.web.controller.monitor; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.zzyl.common.annotation.Log; +import com.zzyl.common.core.controller.BaseController; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.core.page.TableDataInfo; +import com.zzyl.common.enums.BusinessType; +import com.zzyl.common.utils.poi.ExcelUtil; +import com.zzyl.system.domain.SysOperLog; +import com.zzyl.system.service.ISysOperLogService; + +/** + * 操作日志记录 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/monitor/operlog") +public class SysOperlogController extends BaseController +{ + @Autowired + private ISysOperLogService operLogService; + + @PreAuthorize("@ss.hasPermi('monitor:operlog:list')") + @GetMapping("/list") + public TableDataInfo list(SysOperLog operLog) + { + startPage(); + List list = operLogService.selectOperLogList(operLog); + return getDataTable(list); + } + + @Log(title = "操作日志", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('monitor:operlog:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysOperLog operLog) + { + List list = operLogService.selectOperLogList(operLog); + ExcelUtil util = new ExcelUtil(SysOperLog.class); + util.exportExcel(response, list, "操作日志"); + } + + @Log(title = "操作日志", businessType = BusinessType.DELETE) + @PreAuthorize("@ss.hasPermi('monitor:operlog:remove')") + @DeleteMapping("/{operIds}") + public AjaxResult remove(@PathVariable Long[] operIds) + { + return toAjax(operLogService.deleteOperLogByIds(operIds)); + } + + @Log(title = "操作日志", businessType = BusinessType.CLEAN) + @PreAuthorize("@ss.hasPermi('monitor:operlog:remove')") + @DeleteMapping("/clean") + public AjaxResult clean() + { + operLogService.cleanOperLog(); + return success(); + } +} diff --git a/zzyl-admin/src/main/java/com/zzyl/web/controller/monitor/SysUserOnlineController.java b/zzyl-admin/src/main/java/com/zzyl/web/controller/monitor/SysUserOnlineController.java new file mode 100644 index 0000000..558649b --- /dev/null +++ b/zzyl-admin/src/main/java/com/zzyl/web/controller/monitor/SysUserOnlineController.java @@ -0,0 +1,83 @@ +package com.zzyl.web.controller.monitor; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.zzyl.common.annotation.Log; +import com.zzyl.common.constant.CacheConstants; +import com.zzyl.common.core.controller.BaseController; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.core.domain.model.LoginUser; +import com.zzyl.common.core.page.TableDataInfo; +import com.zzyl.common.core.redis.RedisCache; +import com.zzyl.common.enums.BusinessType; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.system.domain.SysUserOnline; +import com.zzyl.system.service.ISysUserOnlineService; + +/** + * 在线用户监控 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/monitor/online") +public class SysUserOnlineController extends BaseController +{ + @Autowired + private ISysUserOnlineService userOnlineService; + + @Autowired + private RedisCache redisCache; + + @PreAuthorize("@ss.hasPermi('monitor:online:list')") + @GetMapping("/list") + public TableDataInfo list(String ipaddr, String userName) + { + Collection keys = redisCache.keys(CacheConstants.LOGIN_TOKEN_KEY + "*"); + List userOnlineList = new ArrayList(); + for (String key : keys) + { + LoginUser user = redisCache.getCacheObject(key); + if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName)) + { + userOnlineList.add(userOnlineService.selectOnlineByInfo(ipaddr, userName, user)); + } + else if (StringUtils.isNotEmpty(ipaddr)) + { + userOnlineList.add(userOnlineService.selectOnlineByIpaddr(ipaddr, user)); + } + else if (StringUtils.isNotEmpty(userName) && StringUtils.isNotNull(user.getUser())) + { + userOnlineList.add(userOnlineService.selectOnlineByUserName(userName, user)); + } + else + { + userOnlineList.add(userOnlineService.loginUserToUserOnline(user)); + } + } + Collections.reverse(userOnlineList); + userOnlineList.removeAll(Collections.singleton(null)); + return getDataTable(userOnlineList); + } + + /** + * 强退用户 + */ + @PreAuthorize("@ss.hasPermi('monitor:online:forceLogout')") + @Log(title = "在线用户", businessType = BusinessType.FORCE) + @DeleteMapping("/{tokenId}") + public AjaxResult forceLogout(@PathVariable String tokenId) + { + redisCache.deleteObject(CacheConstants.LOGIN_TOKEN_KEY + tokenId); + return success(); + } +} diff --git a/zzyl-admin/src/main/java/com/zzyl/web/controller/system/SysConfigController.java b/zzyl-admin/src/main/java/com/zzyl/web/controller/system/SysConfigController.java new file mode 100644 index 0000000..137cbb0 --- /dev/null +++ b/zzyl-admin/src/main/java/com/zzyl/web/controller/system/SysConfigController.java @@ -0,0 +1,133 @@ +package com.zzyl.web.controller.system; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.zzyl.common.annotation.Log; +import com.zzyl.common.core.controller.BaseController; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.core.page.TableDataInfo; +import com.zzyl.common.enums.BusinessType; +import com.zzyl.common.utils.poi.ExcelUtil; +import com.zzyl.system.domain.SysConfig; +import com.zzyl.system.service.ISysConfigService; + +/** + * 参数配置 信息操作处理 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/system/config") +public class SysConfigController extends BaseController +{ + @Autowired + private ISysConfigService configService; + + /** + * 获取参数配置列表 + */ + @PreAuthorize("@ss.hasPermi('system:config:list')") + @GetMapping("/list") + public TableDataInfo list(SysConfig config) + { + startPage(); + List list = configService.selectConfigList(config); + return getDataTable(list); + } + + @Log(title = "参数管理", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('system:config:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysConfig config) + { + List list = configService.selectConfigList(config); + ExcelUtil util = new ExcelUtil(SysConfig.class); + util.exportExcel(response, list, "参数数据"); + } + + /** + * 根据参数编号获取详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:config:query')") + @GetMapping(value = "/{configId}") + public AjaxResult getInfo(@PathVariable Long configId) + { + return success(configService.selectConfigById(configId)); + } + + /** + * 根据参数键名查询参数值 + */ + @GetMapping(value = "/configKey/{configKey}") + public AjaxResult getConfigKey(@PathVariable String configKey) + { + return success(configService.selectConfigByKey(configKey)); + } + + /** + * 新增参数配置 + */ + @PreAuthorize("@ss.hasPermi('system:config:add')") + @Log(title = "参数管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysConfig config) + { + if (!configService.checkConfigKeyUnique(config)) + { + return error("新增参数'" + config.getConfigName() + "'失败,参数键名已存在"); + } + config.setCreateBy(getUsername()); + return toAjax(configService.insertConfig(config)); + } + + /** + * 修改参数配置 + */ + @PreAuthorize("@ss.hasPermi('system:config:edit')") + @Log(title = "参数管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysConfig config) + { + if (!configService.checkConfigKeyUnique(config)) + { + return error("修改参数'" + config.getConfigName() + "'失败,参数键名已存在"); + } + config.setUpdateBy(getUsername()); + return toAjax(configService.updateConfig(config)); + } + + /** + * 删除参数配置 + */ + @PreAuthorize("@ss.hasPermi('system:config:remove')") + @Log(title = "参数管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{configIds}") + public AjaxResult remove(@PathVariable Long[] configIds) + { + configService.deleteConfigByIds(configIds); + return success(); + } + + /** + * 刷新参数缓存 + */ + @PreAuthorize("@ss.hasPermi('system:config:remove')") + @Log(title = "参数管理", businessType = BusinessType.CLEAN) + @DeleteMapping("/refreshCache") + public AjaxResult refreshCache() + { + configService.resetConfigCache(); + return success(); + } +} diff --git a/zzyl-admin/src/main/java/com/zzyl/web/controller/system/SysDeptController.java b/zzyl-admin/src/main/java/com/zzyl/web/controller/system/SysDeptController.java new file mode 100644 index 0000000..f17c045 --- /dev/null +++ b/zzyl-admin/src/main/java/com/zzyl/web/controller/system/SysDeptController.java @@ -0,0 +1,132 @@ +package com.zzyl.web.controller.system; + +import java.util.List; +import org.apache.commons.lang3.ArrayUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.zzyl.common.annotation.Log; +import com.zzyl.common.constant.UserConstants; +import com.zzyl.common.core.controller.BaseController; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.core.domain.entity.SysDept; +import com.zzyl.common.enums.BusinessType; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.system.service.ISysDeptService; + +/** + * 部门信息 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/system/dept") +public class SysDeptController extends BaseController +{ + @Autowired + private ISysDeptService deptService; + + /** + * 获取部门列表 + */ + @PreAuthorize("@ss.hasPermi('system:dept:list')") + @GetMapping("/list") + public AjaxResult list(SysDept dept) + { + List depts = deptService.selectDeptList(dept); + return success(depts); + } + + /** + * 查询部门列表(排除节点) + */ + @PreAuthorize("@ss.hasPermi('system:dept:list')") + @GetMapping("/list/exclude/{deptId}") + public AjaxResult excludeChild(@PathVariable(value = "deptId", required = false) Long deptId) + { + List depts = deptService.selectDeptList(new SysDept()); + depts.removeIf(d -> d.getDeptId().intValue() == deptId || ArrayUtils.contains(StringUtils.split(d.getAncestors(), ","), deptId + "")); + return success(depts); + } + + /** + * 根据部门编号获取详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:dept:query')") + @GetMapping(value = "/{deptId}") + public AjaxResult getInfo(@PathVariable Long deptId) + { + deptService.checkDeptDataScope(deptId); + return success(deptService.selectDeptById(deptId)); + } + + /** + * 新增部门 + */ + @PreAuthorize("@ss.hasPermi('system:dept:add')") + @Log(title = "部门管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysDept dept) + { + if (!deptService.checkDeptNameUnique(dept)) + { + return error("新增部门'" + dept.getDeptName() + "'失败,部门名称已存在"); + } + dept.setCreateBy(getUsername()); + return toAjax(deptService.insertDept(dept)); + } + + /** + * 修改部门 + */ + @PreAuthorize("@ss.hasPermi('system:dept:edit')") + @Log(title = "部门管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysDept dept) + { + Long deptId = dept.getDeptId(); + deptService.checkDeptDataScope(deptId); + if (!deptService.checkDeptNameUnique(dept)) + { + return error("修改部门'" + dept.getDeptName() + "'失败,部门名称已存在"); + } + else if (dept.getParentId().equals(deptId)) + { + return error("修改部门'" + dept.getDeptName() + "'失败,上级部门不能是自己"); + } + else if (StringUtils.equals(UserConstants.DEPT_DISABLE, dept.getStatus()) && deptService.selectNormalChildrenDeptById(deptId) > 0) + { + return error("该部门包含未停用的子部门!"); + } + dept.setUpdateBy(getUsername()); + return toAjax(deptService.updateDept(dept)); + } + + /** + * 删除部门 + */ + @PreAuthorize("@ss.hasPermi('system:dept:remove')") + @Log(title = "部门管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{deptId}") + public AjaxResult remove(@PathVariable Long deptId) + { + if (deptService.hasChildByDeptId(deptId)) + { + return warn("存在下级部门,不允许删除"); + } + if (deptService.checkDeptExistUser(deptId)) + { + return warn("部门存在用户,不允许删除"); + } + deptService.checkDeptDataScope(deptId); + return toAjax(deptService.deleteDeptById(deptId)); + } +} diff --git a/zzyl-admin/src/main/java/com/zzyl/web/controller/system/SysDictDataController.java b/zzyl-admin/src/main/java/com/zzyl/web/controller/system/SysDictDataController.java new file mode 100644 index 0000000..489142c --- /dev/null +++ b/zzyl-admin/src/main/java/com/zzyl/web/controller/system/SysDictDataController.java @@ -0,0 +1,121 @@ +package com.zzyl.web.controller.system; + +import java.util.ArrayList; +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.zzyl.common.annotation.Log; +import com.zzyl.common.core.controller.BaseController; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.core.domain.entity.SysDictData; +import com.zzyl.common.core.page.TableDataInfo; +import com.zzyl.common.enums.BusinessType; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.common.utils.poi.ExcelUtil; +import com.zzyl.system.service.ISysDictDataService; +import com.zzyl.system.service.ISysDictTypeService; + +/** + * 数据字典信息 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/system/dict/data") +public class SysDictDataController extends BaseController +{ + @Autowired + private ISysDictDataService dictDataService; + + @Autowired + private ISysDictTypeService dictTypeService; + + @PreAuthorize("@ss.hasPermi('system:dict:list')") + @GetMapping("/list") + public TableDataInfo list(SysDictData dictData) + { + startPage(); + List list = dictDataService.selectDictDataList(dictData); + return getDataTable(list); + } + + @Log(title = "字典数据", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('system:dict:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysDictData dictData) + { + List list = dictDataService.selectDictDataList(dictData); + ExcelUtil util = new ExcelUtil(SysDictData.class); + util.exportExcel(response, list, "字典数据"); + } + + /** + * 查询字典数据详细 + */ + @PreAuthorize("@ss.hasPermi('system:dict:query')") + @GetMapping(value = "/{dictCode}") + public AjaxResult getInfo(@PathVariable Long dictCode) + { + return success(dictDataService.selectDictDataById(dictCode)); + } + + /** + * 根据字典类型查询字典数据信息 + */ + @GetMapping(value = "/type/{dictType}") + public AjaxResult dictType(@PathVariable String dictType) + { + List data = dictTypeService.selectDictDataByType(dictType); + if (StringUtils.isNull(data)) + { + data = new ArrayList(); + } + return success(data); + } + + /** + * 新增字典类型 + */ + @PreAuthorize("@ss.hasPermi('system:dict:add')") + @Log(title = "字典数据", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysDictData dict) + { + dict.setCreateBy(getUsername()); + return toAjax(dictDataService.insertDictData(dict)); + } + + /** + * 修改保存字典类型 + */ + @PreAuthorize("@ss.hasPermi('system:dict:edit')") + @Log(title = "字典数据", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysDictData dict) + { + dict.setUpdateBy(getUsername()); + return toAjax(dictDataService.updateDictData(dict)); + } + + /** + * 删除字典类型 + */ + @PreAuthorize("@ss.hasPermi('system:dict:remove')") + @Log(title = "字典类型", businessType = BusinessType.DELETE) + @DeleteMapping("/{dictCodes}") + public AjaxResult remove(@PathVariable Long[] dictCodes) + { + dictDataService.deleteDictDataByIds(dictCodes); + return success(); + } +} diff --git a/zzyl-admin/src/main/java/com/zzyl/web/controller/system/SysDictTypeController.java b/zzyl-admin/src/main/java/com/zzyl/web/controller/system/SysDictTypeController.java new file mode 100644 index 0000000..f419d70 --- /dev/null +++ b/zzyl-admin/src/main/java/com/zzyl/web/controller/system/SysDictTypeController.java @@ -0,0 +1,131 @@ +package com.zzyl.web.controller.system; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.zzyl.common.annotation.Log; +import com.zzyl.common.core.controller.BaseController; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.core.domain.entity.SysDictType; +import com.zzyl.common.core.page.TableDataInfo; +import com.zzyl.common.enums.BusinessType; +import com.zzyl.common.utils.poi.ExcelUtil; +import com.zzyl.system.service.ISysDictTypeService; + +/** + * 数据字典信息 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/system/dict/type") +public class SysDictTypeController extends BaseController +{ + @Autowired + private ISysDictTypeService dictTypeService; + + @PreAuthorize("@ss.hasPermi('system:dict:list')") + @GetMapping("/list") + public TableDataInfo list(SysDictType dictType) + { + startPage(); + List list = dictTypeService.selectDictTypeList(dictType); + return getDataTable(list); + } + + @Log(title = "字典类型", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('system:dict:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysDictType dictType) + { + List list = dictTypeService.selectDictTypeList(dictType); + ExcelUtil util = new ExcelUtil(SysDictType.class); + util.exportExcel(response, list, "字典类型"); + } + + /** + * 查询字典类型详细 + */ + @PreAuthorize("@ss.hasPermi('system:dict:query')") + @GetMapping(value = "/{dictId}") + public AjaxResult getInfo(@PathVariable Long dictId) + { + return success(dictTypeService.selectDictTypeById(dictId)); + } + + /** + * 新增字典类型 + */ + @PreAuthorize("@ss.hasPermi('system:dict:add')") + @Log(title = "字典类型", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysDictType dict) + { + if (!dictTypeService.checkDictTypeUnique(dict)) + { + return error("新增字典'" + dict.getDictName() + "'失败,字典类型已存在"); + } + dict.setCreateBy(getUsername()); + return toAjax(dictTypeService.insertDictType(dict)); + } + + /** + * 修改字典类型 + */ + @PreAuthorize("@ss.hasPermi('system:dict:edit')") + @Log(title = "字典类型", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysDictType dict) + { + if (!dictTypeService.checkDictTypeUnique(dict)) + { + return error("修改字典'" + dict.getDictName() + "'失败,字典类型已存在"); + } + dict.setUpdateBy(getUsername()); + return toAjax(dictTypeService.updateDictType(dict)); + } + + /** + * 删除字典类型 + */ + @PreAuthorize("@ss.hasPermi('system:dict:remove')") + @Log(title = "字典类型", businessType = BusinessType.DELETE) + @DeleteMapping("/{dictIds}") + public AjaxResult remove(@PathVariable Long[] dictIds) + { + dictTypeService.deleteDictTypeByIds(dictIds); + return success(); + } + + /** + * 刷新字典缓存 + */ + @PreAuthorize("@ss.hasPermi('system:dict:remove')") + @Log(title = "字典类型", businessType = BusinessType.CLEAN) + @DeleteMapping("/refreshCache") + public AjaxResult refreshCache() + { + dictTypeService.resetDictCache(); + return success(); + } + + /** + * 获取字典选择框列表 + */ + @GetMapping("/optionselect") + public AjaxResult optionselect() + { + List dictTypes = dictTypeService.selectDictTypeAll(); + return success(dictTypes); + } +} diff --git a/zzyl-admin/src/main/java/com/zzyl/web/controller/system/SysIndexController.java b/zzyl-admin/src/main/java/com/zzyl/web/controller/system/SysIndexController.java new file mode 100644 index 0000000..8b8f9b7 --- /dev/null +++ b/zzyl-admin/src/main/java/com/zzyl/web/controller/system/SysIndexController.java @@ -0,0 +1,29 @@ +package com.zzyl.web.controller.system; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.zzyl.common.config.RuoYiConfig; +import com.zzyl.common.utils.StringUtils; + +/** + * 首页 + * + * @author ruoyi + */ +@RestController +public class SysIndexController +{ + /** 系统基础配置 */ + @Autowired + private RuoYiConfig ruoyiConfig; + + /** + * 访问首页,提示语 + */ + @RequestMapping("/") + public String index() + { + return StringUtils.format("欢迎使用{}后台管理框架,当前版本:v{},请通过前端地址访问。", ruoyiConfig.getName(), ruoyiConfig.getVersion()); + } +} diff --git a/zzyl-admin/src/main/java/com/zzyl/web/controller/system/SysLoginController.java b/zzyl-admin/src/main/java/com/zzyl/web/controller/system/SysLoginController.java new file mode 100644 index 0000000..e5afb03 --- /dev/null +++ b/zzyl-admin/src/main/java/com/zzyl/web/controller/system/SysLoginController.java @@ -0,0 +1,97 @@ +package com.zzyl.web.controller.system; + +import java.util.List; +import java.util.Set; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; +import com.zzyl.common.constant.Constants; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.core.domain.entity.SysMenu; +import com.zzyl.common.core.domain.entity.SysUser; +import com.zzyl.common.core.domain.model.LoginBody; +import com.zzyl.common.core.domain.model.LoginUser; +import com.zzyl.common.utils.SecurityUtils; +import com.zzyl.framework.web.service.SysLoginService; +import com.zzyl.framework.web.service.SysPermissionService; +import com.zzyl.framework.web.service.TokenService; +import com.zzyl.system.service.ISysMenuService; + +/** + * 登录验证 + * + * @author ruoyi + */ +@RestController +public class SysLoginController +{ + @Autowired + private SysLoginService loginService; + + @Autowired + private ISysMenuService menuService; + + @Autowired + private SysPermissionService permissionService; + + @Autowired + private TokenService tokenService; + + /** + * 登录方法 + * + * @param loginBody 登录信息 + * @return 结果 + */ + @PostMapping("/login") + public AjaxResult login(@RequestBody LoginBody loginBody) + { + AjaxResult ajax = AjaxResult.success(); + // 生成令牌 + String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(), + loginBody.getUuid()); + ajax.put(Constants.TOKEN, token); + return ajax; + } + + /** + * 获取用户信息 + * + * @return 用户信息 + */ + @GetMapping("getInfo") + public AjaxResult getInfo() + { + LoginUser loginUser = SecurityUtils.getLoginUser(); + SysUser user = loginUser.getUser(); + // 角色集合 + Set roles = permissionService.getRolePermission(user); + // 权限集合 + Set permissions = permissionService.getMenuPermission(user); + if (!loginUser.getPermissions().equals(permissions)) + { + loginUser.setPermissions(permissions); + tokenService.refreshToken(loginUser); + } + AjaxResult ajax = AjaxResult.success(); + ajax.put("user", user); + ajax.put("roles", roles); + ajax.put("permissions", permissions); + return ajax; + } + + /** + * 获取路由信息 + * + * @return 路由信息 + */ + @GetMapping("getRouters") + public AjaxResult getRouters() + { + Long userId = SecurityUtils.getUserId(); + List menus = menuService.selectMenuTreeByUserId(userId); + return AjaxResult.success(menuService.buildMenus(menus)); + } +} diff --git a/zzyl-admin/src/main/java/com/zzyl/web/controller/system/SysMenuController.java b/zzyl-admin/src/main/java/com/zzyl/web/controller/system/SysMenuController.java new file mode 100644 index 0000000..b52bb58 --- /dev/null +++ b/zzyl-admin/src/main/java/com/zzyl/web/controller/system/SysMenuController.java @@ -0,0 +1,142 @@ +package com.zzyl.web.controller.system; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.zzyl.common.annotation.Log; +import com.zzyl.common.constant.UserConstants; +import com.zzyl.common.core.controller.BaseController; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.core.domain.entity.SysMenu; +import com.zzyl.common.enums.BusinessType; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.system.service.ISysMenuService; + +/** + * 菜单信息 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/system/menu") +public class SysMenuController extends BaseController +{ + @Autowired + private ISysMenuService menuService; + + /** + * 获取菜单列表 + */ + @PreAuthorize("@ss.hasPermi('system:menu:list')") + @GetMapping("/list") + public AjaxResult list(SysMenu menu) + { + List menus = menuService.selectMenuList(menu, getUserId()); + return success(menus); + } + + /** + * 根据菜单编号获取详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:menu:query')") + @GetMapping(value = "/{menuId}") + public AjaxResult getInfo(@PathVariable Long menuId) + { + return success(menuService.selectMenuById(menuId)); + } + + /** + * 获取菜单下拉树列表 + */ + @GetMapping("/treeselect") + public AjaxResult treeselect(SysMenu menu) + { + List menus = menuService.selectMenuList(menu, getUserId()); + return success(menuService.buildMenuTreeSelect(menus)); + } + + /** + * 加载对应角色菜单列表树 + */ + @GetMapping(value = "/roleMenuTreeselect/{roleId}") + public AjaxResult roleMenuTreeselect(@PathVariable("roleId") Long roleId) + { + List menus = menuService.selectMenuList(getUserId()); + AjaxResult ajax = AjaxResult.success(); + ajax.put("checkedKeys", menuService.selectMenuListByRoleId(roleId)); + ajax.put("menus", menuService.buildMenuTreeSelect(menus)); + return ajax; + } + + /** + * 新增菜单 + */ + @PreAuthorize("@ss.hasPermi('system:menu:add')") + @Log(title = "菜单管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysMenu menu) + { + if (!menuService.checkMenuNameUnique(menu)) + { + return error("新增菜单'" + menu.getMenuName() + "'失败,菜单名称已存在"); + } + else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) + { + return error("新增菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头"); + } + menu.setCreateBy(getUsername()); + return toAjax(menuService.insertMenu(menu)); + } + + /** + * 修改菜单 + */ + @PreAuthorize("@ss.hasPermi('system:menu:edit')") + @Log(title = "菜单管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysMenu menu) + { + if (!menuService.checkMenuNameUnique(menu)) + { + return error("修改菜单'" + menu.getMenuName() + "'失败,菜单名称已存在"); + } + else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) + { + return error("修改菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头"); + } + else if (menu.getMenuId().equals(menu.getParentId())) + { + return error("修改菜单'" + menu.getMenuName() + "'失败,上级菜单不能选择自己"); + } + menu.setUpdateBy(getUsername()); + return toAjax(menuService.updateMenu(menu)); + } + + /** + * 删除菜单 + */ + @PreAuthorize("@ss.hasPermi('system:menu:remove')") + @Log(title = "菜单管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{menuId}") + public AjaxResult remove(@PathVariable("menuId") Long menuId) + { + if (menuService.hasChildByMenuId(menuId)) + { + return warn("存在子菜单,不允许删除"); + } + if (menuService.checkMenuExistRole(menuId)) + { + return warn("菜单已分配,不允许删除"); + } + return toAjax(menuService.deleteMenuById(menuId)); + } +} \ No newline at end of file diff --git a/zzyl-admin/src/main/java/com/zzyl/web/controller/system/SysNoticeController.java b/zzyl-admin/src/main/java/com/zzyl/web/controller/system/SysNoticeController.java new file mode 100644 index 0000000..4ee2e6e --- /dev/null +++ b/zzyl-admin/src/main/java/com/zzyl/web/controller/system/SysNoticeController.java @@ -0,0 +1,91 @@ +package com.zzyl.web.controller.system; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.zzyl.common.annotation.Log; +import com.zzyl.common.core.controller.BaseController; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.core.page.TableDataInfo; +import com.zzyl.common.enums.BusinessType; +import com.zzyl.system.domain.SysNotice; +import com.zzyl.system.service.ISysNoticeService; + +/** + * 公告 信息操作处理 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/system/notice") +public class SysNoticeController extends BaseController +{ + @Autowired + private ISysNoticeService noticeService; + + /** + * 获取通知公告列表 + */ + @PreAuthorize("@ss.hasPermi('system:notice:list')") + @GetMapping("/list") + public TableDataInfo list(SysNotice notice) + { + startPage(); + List list = noticeService.selectNoticeList(notice); + return getDataTable(list); + } + + /** + * 根据通知公告编号获取详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:notice:query')") + @GetMapping(value = "/{noticeId}") + public AjaxResult getInfo(@PathVariable Long noticeId) + { + return success(noticeService.selectNoticeById(noticeId)); + } + + /** + * 新增通知公告 + */ + @PreAuthorize("@ss.hasPermi('system:notice:add')") + @Log(title = "通知公告", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysNotice notice) + { + notice.setCreateBy(getUsername()); + return toAjax(noticeService.insertNotice(notice)); + } + + /** + * 修改通知公告 + */ + @PreAuthorize("@ss.hasPermi('system:notice:edit')") + @Log(title = "通知公告", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysNotice notice) + { + notice.setUpdateBy(getUsername()); + return toAjax(noticeService.updateNotice(notice)); + } + + /** + * 删除通知公告 + */ + @PreAuthorize("@ss.hasPermi('system:notice:remove')") + @Log(title = "通知公告", businessType = BusinessType.DELETE) + @DeleteMapping("/{noticeIds}") + public AjaxResult remove(@PathVariable Long[] noticeIds) + { + return toAjax(noticeService.deleteNoticeByIds(noticeIds)); + } +} diff --git a/zzyl-admin/src/main/java/com/zzyl/web/controller/system/SysPostController.java b/zzyl-admin/src/main/java/com/zzyl/web/controller/system/SysPostController.java new file mode 100644 index 0000000..3808c68 --- /dev/null +++ b/zzyl-admin/src/main/java/com/zzyl/web/controller/system/SysPostController.java @@ -0,0 +1,129 @@ +package com.zzyl.web.controller.system; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.zzyl.common.annotation.Log; +import com.zzyl.common.core.controller.BaseController; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.core.page.TableDataInfo; +import com.zzyl.common.enums.BusinessType; +import com.zzyl.common.utils.poi.ExcelUtil; +import com.zzyl.system.domain.SysPost; +import com.zzyl.system.service.ISysPostService; + +/** + * 岗位信息操作处理 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/system/post") +public class SysPostController extends BaseController +{ + @Autowired + private ISysPostService postService; + + /** + * 获取岗位列表 + */ + @PreAuthorize("@ss.hasPermi('system:post:list')") + @GetMapping("/list") + public TableDataInfo list(SysPost post) + { + startPage(); + List list = postService.selectPostList(post); + return getDataTable(list); + } + + @Log(title = "岗位管理", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('system:post:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysPost post) + { + List list = postService.selectPostList(post); + ExcelUtil util = new ExcelUtil(SysPost.class); + util.exportExcel(response, list, "岗位数据"); + } + + /** + * 根据岗位编号获取详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:post:query')") + @GetMapping(value = "/{postId}") + public AjaxResult getInfo(@PathVariable Long postId) + { + return success(postService.selectPostById(postId)); + } + + /** + * 新增岗位 + */ + @PreAuthorize("@ss.hasPermi('system:post:add')") + @Log(title = "岗位管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysPost post) + { + if (!postService.checkPostNameUnique(post)) + { + return error("新增岗位'" + post.getPostName() + "'失败,岗位名称已存在"); + } + else if (!postService.checkPostCodeUnique(post)) + { + return error("新增岗位'" + post.getPostName() + "'失败,岗位编码已存在"); + } + post.setCreateBy(getUsername()); + return toAjax(postService.insertPost(post)); + } + + /** + * 修改岗位 + */ + @PreAuthorize("@ss.hasPermi('system:post:edit')") + @Log(title = "岗位管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysPost post) + { + if (!postService.checkPostNameUnique(post)) + { + return error("修改岗位'" + post.getPostName() + "'失败,岗位名称已存在"); + } + else if (!postService.checkPostCodeUnique(post)) + { + return error("修改岗位'" + post.getPostName() + "'失败,岗位编码已存在"); + } + post.setUpdateBy(getUsername()); + return toAjax(postService.updatePost(post)); + } + + /** + * 删除岗位 + */ + @PreAuthorize("@ss.hasPermi('system:post:remove')") + @Log(title = "岗位管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{postIds}") + public AjaxResult remove(@PathVariable Long[] postIds) + { + return toAjax(postService.deletePostByIds(postIds)); + } + + /** + * 获取岗位选择框列表 + */ + @GetMapping("/optionselect") + public AjaxResult optionselect() + { + List posts = postService.selectPostAll(); + return success(posts); + } +} diff --git a/zzyl-admin/src/main/java/com/zzyl/web/controller/system/SysProfileController.java b/zzyl-admin/src/main/java/com/zzyl/web/controller/system/SysProfileController.java new file mode 100644 index 0000000..d4011e2 --- /dev/null +++ b/zzyl-admin/src/main/java/com/zzyl/web/controller/system/SysProfileController.java @@ -0,0 +1,140 @@ +package com.zzyl.web.controller.system; + +import java.util.Map; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; +import com.zzyl.common.annotation.Log; +import com.zzyl.common.config.RuoYiConfig; +import com.zzyl.common.core.controller.BaseController; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.core.domain.entity.SysUser; +import com.zzyl.common.core.domain.model.LoginUser; +import com.zzyl.common.enums.BusinessType; +import com.zzyl.common.utils.SecurityUtils; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.common.utils.file.FileUploadUtils; +import com.zzyl.common.utils.file.MimeTypeUtils; +import com.zzyl.framework.web.service.TokenService; +import com.zzyl.system.service.ISysUserService; + +/** + * 个人信息 业务处理 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/system/user/profile") +public class SysProfileController extends BaseController +{ + @Autowired + private ISysUserService userService; + + @Autowired + private TokenService tokenService; + + /** + * 个人信息 + */ + @GetMapping + public AjaxResult profile() + { + LoginUser loginUser = getLoginUser(); + SysUser user = loginUser.getUser(); + AjaxResult ajax = AjaxResult.success(user); + ajax.put("roleGroup", userService.selectUserRoleGroup(loginUser.getUsername())); + ajax.put("postGroup", userService.selectUserPostGroup(loginUser.getUsername())); + return ajax; + } + + /** + * 修改用户 + */ + @Log(title = "个人信息", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult updateProfile(@RequestBody SysUser user) + { + LoginUser loginUser = getLoginUser(); + SysUser currentUser = loginUser.getUser(); + currentUser.setNickName(user.getNickName()); + currentUser.setEmail(user.getEmail()); + currentUser.setPhonenumber(user.getPhonenumber()); + currentUser.setSex(user.getSex()); + if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(currentUser)) + { + return error("修改用户'" + loginUser.getUsername() + "'失败,手机号码已存在"); + } + if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(currentUser)) + { + return error("修改用户'" + loginUser.getUsername() + "'失败,邮箱账号已存在"); + } + if (userService.updateUserProfile(currentUser) > 0) + { + // 更新缓存用户信息 + tokenService.setLoginUser(loginUser); + return success(); + } + return error("修改个人信息异常,请联系管理员"); + } + + /** + * 重置密码 + */ + @Log(title = "个人信息", businessType = BusinessType.UPDATE) + @PutMapping("/updatePwd") + public AjaxResult updatePwd(@RequestBody Map params) + { + String oldPassword = params.get("oldPassword"); + String newPassword = params.get("newPassword"); + LoginUser loginUser = getLoginUser(); + String userName = loginUser.getUsername(); + String password = loginUser.getPassword(); + if (!SecurityUtils.matchesPassword(oldPassword, password)) + { + return error("修改密码失败,旧密码错误"); + } + if (SecurityUtils.matchesPassword(newPassword, password)) + { + return error("新密码不能与旧密码相同"); + } + newPassword = SecurityUtils.encryptPassword(newPassword); + if (userService.resetUserPwd(userName, newPassword) > 0) + { + // 更新缓存用户密码 + loginUser.getUser().setPassword(newPassword); + tokenService.setLoginUser(loginUser); + return success(); + } + return error("修改密码异常,请联系管理员"); + } + + /** + * 头像上传 + */ + @Log(title = "用户头像", businessType = BusinessType.UPDATE) + @PostMapping("/avatar") + public AjaxResult avatar(@RequestParam("avatarfile") MultipartFile file) throws Exception + { + if (!file.isEmpty()) + { + LoginUser loginUser = getLoginUser(); + String avatar = FileUploadUtils.upload(RuoYiConfig.getAvatarPath(), file, MimeTypeUtils.IMAGE_EXTENSION); + if (userService.updateUserAvatar(loginUser.getUsername(), avatar)) + { + AjaxResult ajax = AjaxResult.success(); + ajax.put("imgUrl", avatar); + // 更新缓存用户头像 + loginUser.getUser().setAvatar(avatar); + tokenService.setLoginUser(loginUser); + return ajax; + } + } + return error("上传图片异常,请联系管理员"); + } +} diff --git a/zzyl-admin/src/main/java/com/zzyl/web/controller/system/SysRegisterController.java b/zzyl-admin/src/main/java/com/zzyl/web/controller/system/SysRegisterController.java new file mode 100644 index 0000000..ff0cf52 --- /dev/null +++ b/zzyl-admin/src/main/java/com/zzyl/web/controller/system/SysRegisterController.java @@ -0,0 +1,38 @@ +package com.zzyl.web.controller.system; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; +import com.zzyl.common.core.controller.BaseController; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.core.domain.model.RegisterBody; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.framework.web.service.SysRegisterService; +import com.zzyl.system.service.ISysConfigService; + +/** + * 注册验证 + * + * @author ruoyi + */ +@RestController +public class SysRegisterController extends BaseController +{ + @Autowired + private SysRegisterService registerService; + + @Autowired + private ISysConfigService configService; + + @PostMapping("/register") + public AjaxResult register(@RequestBody RegisterBody user) + { + if (!("true".equals(configService.selectConfigByKey("sys.account.registerUser")))) + { + return error("当前系统没有开启注册功能!"); + } + String msg = registerService.register(user); + return StringUtils.isEmpty(msg) ? success() : error(msg); + } +} diff --git a/zzyl-admin/src/main/java/com/zzyl/web/controller/system/SysRoleController.java b/zzyl-admin/src/main/java/com/zzyl/web/controller/system/SysRoleController.java new file mode 100644 index 0000000..ce83cd0 --- /dev/null +++ b/zzyl-admin/src/main/java/com/zzyl/web/controller/system/SysRoleController.java @@ -0,0 +1,262 @@ +package com.zzyl.web.controller.system; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.zzyl.common.annotation.Log; +import com.zzyl.common.core.controller.BaseController; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.core.domain.entity.SysDept; +import com.zzyl.common.core.domain.entity.SysRole; +import com.zzyl.common.core.domain.entity.SysUser; +import com.zzyl.common.core.domain.model.LoginUser; +import com.zzyl.common.core.page.TableDataInfo; +import com.zzyl.common.enums.BusinessType; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.common.utils.poi.ExcelUtil; +import com.zzyl.framework.web.service.SysPermissionService; +import com.zzyl.framework.web.service.TokenService; +import com.zzyl.system.domain.SysUserRole; +import com.zzyl.system.service.ISysDeptService; +import com.zzyl.system.service.ISysRoleService; +import com.zzyl.system.service.ISysUserService; + +/** + * 角色信息 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/system/role") +public class SysRoleController extends BaseController +{ + @Autowired + private ISysRoleService roleService; + + @Autowired + private TokenService tokenService; + + @Autowired + private SysPermissionService permissionService; + + @Autowired + private ISysUserService userService; + + @Autowired + private ISysDeptService deptService; + + @PreAuthorize("@ss.hasPermi('system:role:list')") + @GetMapping("/list") + public TableDataInfo list(SysRole role) + { + startPage(); + List list = roleService.selectRoleList(role); + return getDataTable(list); + } + + @Log(title = "角色管理", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('system:role:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysRole role) + { + List list = roleService.selectRoleList(role); + ExcelUtil util = new ExcelUtil(SysRole.class); + util.exportExcel(response, list, "角色数据"); + } + + /** + * 根据角色编号获取详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:role:query')") + @GetMapping(value = "/{roleId}") + public AjaxResult getInfo(@PathVariable Long roleId) + { + roleService.checkRoleDataScope(roleId); + return success(roleService.selectRoleById(roleId)); + } + + /** + * 新增角色 + */ + @PreAuthorize("@ss.hasPermi('system:role:add')") + @Log(title = "角色管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysRole role) + { + if (!roleService.checkRoleNameUnique(role)) + { + return error("新增角色'" + role.getRoleName() + "'失败,角色名称已存在"); + } + else if (!roleService.checkRoleKeyUnique(role)) + { + return error("新增角色'" + role.getRoleName() + "'失败,角色权限已存在"); + } + role.setCreateBy(getUsername()); + return toAjax(roleService.insertRole(role)); + + } + + /** + * 修改保存角色 + */ + @PreAuthorize("@ss.hasPermi('system:role:edit')") + @Log(title = "角色管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysRole role) + { + roleService.checkRoleAllowed(role); + roleService.checkRoleDataScope(role.getRoleId()); + if (!roleService.checkRoleNameUnique(role)) + { + return error("修改角色'" + role.getRoleName() + "'失败,角色名称已存在"); + } + else if (!roleService.checkRoleKeyUnique(role)) + { + return error("修改角色'" + role.getRoleName() + "'失败,角色权限已存在"); + } + role.setUpdateBy(getUsername()); + + if (roleService.updateRole(role) > 0) + { + // 更新缓存用户权限 + LoginUser loginUser = getLoginUser(); + if (StringUtils.isNotNull(loginUser.getUser()) && !loginUser.getUser().isAdmin()) + { + loginUser.setUser(userService.selectUserByUserName(loginUser.getUser().getUserName())); + loginUser.setPermissions(permissionService.getMenuPermission(loginUser.getUser())); + tokenService.setLoginUser(loginUser); + } + return success(); + } + return error("修改角色'" + role.getRoleName() + "'失败,请联系管理员"); + } + + /** + * 修改保存数据权限 + */ + @PreAuthorize("@ss.hasPermi('system:role:edit')") + @Log(title = "角色管理", businessType = BusinessType.UPDATE) + @PutMapping("/dataScope") + public AjaxResult dataScope(@RequestBody SysRole role) + { + roleService.checkRoleAllowed(role); + roleService.checkRoleDataScope(role.getRoleId()); + return toAjax(roleService.authDataScope(role)); + } + + /** + * 状态修改 + */ + @PreAuthorize("@ss.hasPermi('system:role:edit')") + @Log(title = "角色管理", businessType = BusinessType.UPDATE) + @PutMapping("/changeStatus") + public AjaxResult changeStatus(@RequestBody SysRole role) + { + roleService.checkRoleAllowed(role); + roleService.checkRoleDataScope(role.getRoleId()); + role.setUpdateBy(getUsername()); + return toAjax(roleService.updateRoleStatus(role)); + } + + /** + * 删除角色 + */ + @PreAuthorize("@ss.hasPermi('system:role:remove')") + @Log(title = "角色管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{roleIds}") + public AjaxResult remove(@PathVariable Long[] roleIds) + { + return toAjax(roleService.deleteRoleByIds(roleIds)); + } + + /** + * 获取角色选择框列表 + */ + @PreAuthorize("@ss.hasPermi('system:role:query')") + @GetMapping("/optionselect") + public AjaxResult optionselect() + { + return success(roleService.selectRoleAll()); + } + + /** + * 查询已分配用户角色列表 + */ + @PreAuthorize("@ss.hasPermi('system:role:list')") + @GetMapping("/authUser/allocatedList") + public TableDataInfo allocatedList(SysUser user) + { + startPage(); + List list = userService.selectAllocatedList(user); + return getDataTable(list); + } + + /** + * 查询未分配用户角色列表 + */ + @PreAuthorize("@ss.hasPermi('system:role:list')") + @GetMapping("/authUser/unallocatedList") + public TableDataInfo unallocatedList(SysUser user) + { + startPage(); + List list = userService.selectUnallocatedList(user); + return getDataTable(list); + } + + /** + * 取消授权用户 + */ + @PreAuthorize("@ss.hasPermi('system:role:edit')") + @Log(title = "角色管理", businessType = BusinessType.GRANT) + @PutMapping("/authUser/cancel") + public AjaxResult cancelAuthUser(@RequestBody SysUserRole userRole) + { + return toAjax(roleService.deleteAuthUser(userRole)); + } + + /** + * 批量取消授权用户 + */ + @PreAuthorize("@ss.hasPermi('system:role:edit')") + @Log(title = "角色管理", businessType = BusinessType.GRANT) + @PutMapping("/authUser/cancelAll") + public AjaxResult cancelAuthUserAll(Long roleId, Long[] userIds) + { + return toAjax(roleService.deleteAuthUsers(roleId, userIds)); + } + + /** + * 批量选择用户授权 + */ + @PreAuthorize("@ss.hasPermi('system:role:edit')") + @Log(title = "角色管理", businessType = BusinessType.GRANT) + @PutMapping("/authUser/selectAll") + public AjaxResult selectAuthUserAll(Long roleId, Long[] userIds) + { + roleService.checkRoleDataScope(roleId); + return toAjax(roleService.insertAuthUsers(roleId, userIds)); + } + + /** + * 获取对应角色部门树列表 + */ + @PreAuthorize("@ss.hasPermi('system:role:query')") + @GetMapping(value = "/deptTree/{roleId}") + public AjaxResult deptTree(@PathVariable("roleId") Long roleId) + { + AjaxResult ajax = AjaxResult.success(); + ajax.put("checkedKeys", deptService.selectDeptListByRoleId(roleId)); + ajax.put("depts", deptService.selectDeptTreeList(new SysDept())); + return ajax; + } +} diff --git a/zzyl-admin/src/main/java/com/zzyl/web/controller/system/SysUserController.java b/zzyl-admin/src/main/java/com/zzyl/web/controller/system/SysUserController.java new file mode 100644 index 0000000..2348583 --- /dev/null +++ b/zzyl-admin/src/main/java/com/zzyl/web/controller/system/SysUserController.java @@ -0,0 +1,272 @@ +package com.zzyl.web.controller.system; + +import java.util.List; +import java.util.stream.Collectors; +import javax.servlet.http.HttpServletResponse; + +import io.swagger.annotations.ApiOperation; +import org.apache.commons.lang3.ArrayUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; +import com.zzyl.common.annotation.Log; +import com.zzyl.common.core.controller.BaseController; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.core.domain.entity.SysDept; +import com.zzyl.common.core.domain.entity.SysRole; +import com.zzyl.common.core.domain.entity.SysUser; +import com.zzyl.common.core.page.TableDataInfo; +import com.zzyl.common.enums.BusinessType; +import com.zzyl.common.utils.SecurityUtils; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.common.utils.poi.ExcelUtil; +import com.zzyl.system.service.ISysDeptService; +import com.zzyl.system.service.ISysPostService; +import com.zzyl.system.service.ISysRoleService; +import com.zzyl.system.service.ISysUserService; + +/** + * 用户信息 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/system/user") +public class SysUserController extends BaseController +{ + @Autowired + private ISysUserService userService; + + @Autowired + private ISysRoleService roleService; + + @Autowired + private ISysDeptService deptService; + + @Autowired + private ISysPostService postService; + + @Value("${dept.nursingId}") + private String nursingId; + + /** + * 获取用户列表 + */ + @PreAuthorize("@ss.hasPermi('system:user:list')") + @GetMapping("/list") + public TableDataInfo list(SysUser user) + { + startPage(); + List list = userService.selectUserList(user); + return getDataTable(list); + } + + @Log(title = "用户管理", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('system:user:export')") + @PostMapping("/export") + public void export(HttpServletResponse response, SysUser user) + { + List list = userService.selectUserList(user); + ExcelUtil util = new ExcelUtil(SysUser.class); + util.exportExcel(response, list, "用户数据"); + } + + @Log(title = "用户管理", businessType = BusinessType.IMPORT) + @PreAuthorize("@ss.hasPermi('system:user:import')") + @PostMapping("/importData") + public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception + { + ExcelUtil util = new ExcelUtil(SysUser.class); + List userList = util.importExcel(file.getInputStream()); + String operName = getUsername(); + String message = userService.importUser(userList, updateSupport, operName); + return success(message); + } + + @PostMapping("/importTemplate") + public void importTemplate(HttpServletResponse response) + { + ExcelUtil util = new ExcelUtil(SysUser.class); + util.importTemplateExcel(response, "用户数据"); + } + + /** + * 根据用户编号获取详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:user:query')") + @GetMapping(value = { "/", "/{userId}" }) + public AjaxResult getInfo(@PathVariable(value = "userId", required = false) Long userId) + { + AjaxResult ajax = AjaxResult.success(); + if (StringUtils.isNotNull(userId)) + { + userService.checkUserDataScope(userId); + SysUser sysUser = userService.selectUserById(userId); + ajax.put(AjaxResult.DATA_TAG, sysUser); + ajax.put("postIds", postService.selectPostListByUserId(userId)); + ajax.put("roleIds", sysUser.getRoles().stream().map(SysRole::getRoleId).collect(Collectors.toList())); + } + List roles = roleService.selectRoleAll(); + ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList())); + ajax.put("posts", postService.selectPostAll()); + return ajax; + } + + /** + * 新增用户 + */ + @PreAuthorize("@ss.hasPermi('system:user:add')") + @Log(title = "用户管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysUser user) + { + deptService.checkDeptDataScope(user.getDeptId()); + roleService.checkRoleDataScope(user.getRoleIds()); + if (!userService.checkUserNameUnique(user)) + { + return error("新增用户'" + user.getUserName() + "'失败,登录账号已存在"); + } + else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) + { + return error("新增用户'" + user.getUserName() + "'失败,手机号码已存在"); + } + else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) + { + return error("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在"); + } + user.setCreateBy(getUsername()); + user.setPassword(SecurityUtils.encryptPassword(user.getPassword())); + return toAjax(userService.insertUser(user)); + } + + /** + * 修改用户 + */ + @PreAuthorize("@ss.hasPermi('system:user:edit')") + @Log(title = "用户管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysUser user) + { + userService.checkUserAllowed(user); + userService.checkUserDataScope(user.getUserId()); + deptService.checkDeptDataScope(user.getDeptId()); + roleService.checkRoleDataScope(user.getRoleIds()); + if (!userService.checkUserNameUnique(user)) + { + return error("修改用户'" + user.getUserName() + "'失败,登录账号已存在"); + } + else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) + { + return error("修改用户'" + user.getUserName() + "'失败,手机号码已存在"); + } + else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) + { + return error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在"); + } + user.setUpdateBy(getUsername()); + return toAjax(userService.updateUser(user)); + } + + /** + * 删除用户 + */ + @PreAuthorize("@ss.hasPermi('system:user:remove')") + @Log(title = "用户管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{userIds}") + public AjaxResult remove(@PathVariable Long[] userIds) + { + if (ArrayUtils.contains(userIds, getUserId())) + { + return error("当前用户不能删除"); + } + return toAjax(userService.deleteUserByIds(userIds)); + } + + /** + * 重置密码 + */ + @PreAuthorize("@ss.hasPermi('system:user:resetPwd')") + @Log(title = "用户管理", businessType = BusinessType.UPDATE) + @PutMapping("/resetPwd") + public AjaxResult resetPwd(@RequestBody SysUser user) + { + userService.checkUserAllowed(user); + userService.checkUserDataScope(user.getUserId()); + user.setPassword(SecurityUtils.encryptPassword(user.getPassword())); + user.setUpdateBy(getUsername()); + return toAjax(userService.resetPwd(user)); + } + + /** + * 状态修改 + */ + @PreAuthorize("@ss.hasPermi('system:user:edit')") + @Log(title = "用户管理", businessType = BusinessType.UPDATE) + @PutMapping("/changeStatus") + public AjaxResult changeStatus(@RequestBody SysUser user) + { + userService.checkUserAllowed(user); + userService.checkUserDataScope(user.getUserId()); + user.setUpdateBy(getUsername()); + return toAjax(userService.updateUserStatus(user)); + } + + /** + * 根据用户编号获取授权角色 + */ + @PreAuthorize("@ss.hasPermi('system:user:query')") + @GetMapping("/authRole/{userId}") + public AjaxResult authRole(@PathVariable("userId") Long userId) + { + AjaxResult ajax = AjaxResult.success(); + SysUser user = userService.selectUserById(userId); + List roles = roleService.selectRolesByUserId(userId); + ajax.put("user", user); + ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList())); + return ajax; + } + + /** + * 用户授权角色 + */ + @PreAuthorize("@ss.hasPermi('system:user:edit')") + @Log(title = "用户管理", businessType = BusinessType.GRANT) + @PutMapping("/authRole") + public AjaxResult insertAuthRole(Long userId, Long[] roleIds) + { + userService.checkUserDataScope(userId); + roleService.checkRoleDataScope(roleIds); + userService.insertUserAuth(userId, roleIds); + return success(); + } + + /** + * 获取部门树列表 + */ + @PreAuthorize("@ss.hasPermi('system:user:list')") + @GetMapping("/deptTree") + public AjaxResult deptTree(SysDept dept) + { + return success(deptService.selectDeptTreeList(dept)); + } + + /** + * 根据部门编号,查询员工列表 + */ + @ApiOperation("根据部门编号,查询员工列表") + @GetMapping("/listByDeptId") + public AjaxResult getUserListByDept(Long deptId) { + List userListByDept = userService.getUserListByDept(Long.valueOf(nursingId)); + return AjaxResult.success(userListByDept); + } +} diff --git a/zzyl-admin/src/main/java/com/zzyl/web/controller/tool/TestController.java b/zzyl-admin/src/main/java/com/zzyl/web/controller/tool/TestController.java new file mode 100644 index 0000000..648a62d --- /dev/null +++ b/zzyl-admin/src/main/java/com/zzyl/web/controller/tool/TestController.java @@ -0,0 +1,183 @@ +package com.zzyl.web.controller.tool; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.zzyl.common.core.controller.BaseController; +import com.zzyl.common.core.domain.R; +import com.zzyl.common.utils.StringUtils; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import io.swagger.annotations.ApiOperation; + +/** + * swagger 用户测试方法 + * + * @author ruoyi + */ +@Api("用户信息管理") +@RestController +@RequestMapping("/test/user") +public class TestController extends BaseController +{ + private final static Map users = new LinkedHashMap(); + { + users.put(1, new UserEntity(1, "admin", "admin123", "15888888888")); + users.put(2, new UserEntity(2, "ry", "admin123", "15666666666")); + } + + @ApiOperation("获取用户列表") + @GetMapping("/list") + public R> userList() + { + List userList = new ArrayList(users.values()); + return R.ok(userList); + } + + @ApiOperation("获取用户详细") + @ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class) + @GetMapping("/{userId}") + public R getUser(@PathVariable Integer userId) + { + if (!users.isEmpty() && users.containsKey(userId)) + { + return R.ok(users.get(userId)); + } + else + { + return R.fail("用户不存在"); + } + } + + @ApiOperation("新增用户") + @ApiImplicitParams({ + @ApiImplicitParam(name = "userId", value = "用户id", dataType = "Integer", dataTypeClass = Integer.class), + @ApiImplicitParam(name = "username", value = "用户名称", dataType = "String", dataTypeClass = String.class), + @ApiImplicitParam(name = "password", value = "用户密码", dataType = "String", dataTypeClass = String.class), + @ApiImplicitParam(name = "mobile", value = "用户手机", dataType = "String", dataTypeClass = String.class) + }) + @PostMapping("/save") + public R save(UserEntity user) + { + if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId())) + { + return R.fail("用户ID不能为空"); + } + users.put(user.getUserId(), user); + return R.ok(); + } + + @ApiOperation("更新用户") + @PutMapping("/update") + public R update(@RequestBody UserEntity user) + { + if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId())) + { + return R.fail("用户ID不能为空"); + } + if (users.isEmpty() || !users.containsKey(user.getUserId())) + { + return R.fail("用户不存在"); + } + users.remove(user.getUserId()); + users.put(user.getUserId(), user); + return R.ok(); + } + + @ApiOperation("删除用户信息") + @ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class) + @DeleteMapping("/{userId}") + public R delete(@PathVariable Integer userId) + { + if (!users.isEmpty() && users.containsKey(userId)) + { + users.remove(userId); + return R.ok(); + } + else + { + return R.fail("用户不存在"); + } + } +} + +@ApiModel(value = "UserEntity", description = "用户实体") +class UserEntity +{ + @ApiModelProperty("用户ID") + private Integer userId; + + @ApiModelProperty("用户名称") + private String username; + + @ApiModelProperty("用户密码") + private String password; + + @ApiModelProperty("用户手机") + private String mobile; + + public UserEntity() + { + + } + + public UserEntity(Integer userId, String username, String password, String mobile) + { + this.userId = userId; + this.username = username; + this.password = password; + this.mobile = mobile; + } + + public Integer getUserId() + { + return userId; + } + + public void setUserId(Integer userId) + { + this.userId = userId; + } + + public String getUsername() + { + return username; + } + + public void setUsername(String username) + { + this.username = username; + } + + public String getPassword() + { + return password; + } + + public void setPassword(String password) + { + this.password = password; + } + + public String getMobile() + { + return mobile; + } + + public void setMobile(String mobile) + { + this.mobile = mobile; + } +} diff --git a/zzyl-admin/src/main/java/com/zzyl/web/core/config/SwaggerConfig.java b/zzyl-admin/src/main/java/com/zzyl/web/core/config/SwaggerConfig.java new file mode 100644 index 0000000..ec0fa9c --- /dev/null +++ b/zzyl-admin/src/main/java/com/zzyl/web/core/config/SwaggerConfig.java @@ -0,0 +1,125 @@ +package com.zzyl.web.core.config; + +import java.util.ArrayList; +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import com.zzyl.common.config.RuoYiConfig; +import io.swagger.annotations.ApiOperation; +import io.swagger.models.auth.In; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.service.ApiKey; +import springfox.documentation.service.AuthorizationScope; +import springfox.documentation.service.Contact; +import springfox.documentation.service.SecurityReference; +import springfox.documentation.service.SecurityScheme; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spi.service.contexts.SecurityContext; +import springfox.documentation.spring.web.plugins.Docket; + +/** + * Swagger2的接口配置 + * + * @author ruoyi + */ +@Configuration +public class SwaggerConfig +{ + /** 系统基础配置 */ + @Autowired + private RuoYiConfig ruoyiConfig; + + /** 是否开启swagger */ + @Value("${swagger.enabled}") + private boolean enabled; + + /** 设置请求的统一前缀 */ + @Value("${swagger.pathMapping}") + private String pathMapping; + + /** + * 创建API + */ + @Bean + public Docket createRestApi() + { + return new Docket(DocumentationType.OAS_30) + // 是否启用Swagger + .enable(enabled) + // 用来创建该API的基本信息,展示在文档的页面中(自定义展示的信息) + .apiInfo(apiInfo()) + // 设置哪些接口暴露给Swagger展示 + .select() + // 扫描所有有注解的api,用这种方式更灵活 + .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) + // 扫描指定包中的swagger注解 + // .apis(RequestHandlerSelectors.basePackage("com.zzyl.project.tool.swagger")) + // 扫描所有 .apis(RequestHandlerSelectors.any()) + .paths(PathSelectors.any()) + .build() + /* 设置安全模式,swagger可以设置访问token */ + .securitySchemes(securitySchemes()) + .securityContexts(securityContexts()) + .pathMapping(pathMapping); + } + + /** + * 安全模式,这里指定token通过Authorization头请求头传递 + */ + private List securitySchemes() + { + List apiKeyList = new ArrayList(); + apiKeyList.add(new ApiKey("Authorization", "Authorization", In.HEADER.toValue())); + return apiKeyList; + } + + /** + * 安全上下文 + */ + private List securityContexts() + { + List securityContexts = new ArrayList<>(); + securityContexts.add( + SecurityContext.builder() + .securityReferences(defaultAuth()) + .operationSelector(o -> o.requestMappingPattern().matches("/.*")) + .build()); + return securityContexts; + } + + /** + * 默认的安全上引用 + */ + private List defaultAuth() + { + AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything"); + AuthorizationScope[] authorizationScopes = new AuthorizationScope[1]; + authorizationScopes[0] = authorizationScope; + List securityReferences = new ArrayList<>(); + securityReferences.add(new SecurityReference("Authorization", authorizationScopes)); + return securityReferences; + } + + /** + * 添加摘要信息 + */ + private ApiInfo apiInfo() + { + // 用ApiInfoBuilder进行定制 + return new ApiInfoBuilder() + // 设置标题 + .title("标题:中州养老_接口文档") + // 描述 + .description("描述:用于管理中州养老后端接口") + // 作者信息 + .contact(new Contact(ruoyiConfig.getName(), null, null)) + // 版本 + .version("版本号:" + ruoyiConfig.getVersion()) + .build(); + } +} diff --git a/zzyl-admin/src/main/resources/META-INF/spring-devtools.properties b/zzyl-admin/src/main/resources/META-INF/spring-devtools.properties new file mode 100644 index 0000000..37e7b58 --- /dev/null +++ b/zzyl-admin/src/main/resources/META-INF/spring-devtools.properties @@ -0,0 +1 @@ +restart.include.json=/com.alibaba.fastjson2.*.jar \ No newline at end of file diff --git a/zzyl-admin/src/main/resources/application-dev.yml b/zzyl-admin/src/main/resources/application-dev.yml new file mode 100644 index 0000000..6f613fc --- /dev/null +++ b/zzyl-admin/src/main/resources/application-dev.yml @@ -0,0 +1,231 @@ +# 项目相关配置 +ruoyi: + # 名称 + name: zzyl + # 版本 + version: 3.8.8 + # 版权年份 + copyrightYear: 2024 + # 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath) + profile: D:/JAVAdevelop/ruoyi/uploadPath + # 获取ip地址开关 + addressEnabled: false + # 验证码类型 math 数字计算 char 字符验证 + captchaType: math + +# 开发环境配置 +server: + # 服务器的HTTP端口,默认为8080 + port: 9003 + servlet: + # 应用的访问路径 + context-path: / + tomcat: + # tomcat的URI编码 + uri-encoding: UTF-8 + # 连接数满后的排队数,默认为100 + accept-count: 1000 + threads: + # tomcat最大线程数,默认为200 + max: 800 + # Tomcat启动初始化的线程数,默认值10 + min-spare: 100 + +# 日志配置 +logging: + level: + com.zzyl: debug + org.springframework: warn + +# 用户配置 +user: + password: + # 密码最大错误次数 + maxRetryCount: 5 + # 密码锁定时间(默认10分钟) + lockTime: 10 + +# Spring配置 +# 数据源配置 +spring: + datasource: + type: com.alibaba.druid.pool.DruidDataSource + driverClassName: com.mysql.cj.jdbc.Driver + druid: + # 主库数据源 + master: + url: jdbc:mysql://192.168.100.168:3306/zzyl?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 + username: root + password: heima123 + # 从库数据源 + slave: + # 从数据源开关/默认关闭 + enabled: false + url: + username: + password: + # 初始连接数 + initialSize: 5 + # 最小连接池数量 + minIdle: 10 + # 最大连接池数量 + maxActive: 20 + # 配置获取连接等待超时的时间 + maxWait: 60000 + # 配置连接超时时间 + connectTimeout: 30000 + # 配置网络超时时间 + socketTimeout: 60000 + # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 + timeBetweenEvictionRunsMillis: 60000 + # 配置一个连接在池中最小生存的时间,单位是毫秒 + minEvictableIdleTimeMillis: 300000 + # 配置一个连接在池中最大生存的时间,单位是毫秒 + maxEvictableIdleTimeMillis: 900000 + # 配置检测连接是否有效 + validationQuery: SELECT 1 FROM DUAL + testWhileIdle: true + testOnBorrow: false + testOnReturn: false + webStatFilter: + enabled: true + statViewServlet: + enabled: true + # 设置白名单,不填则允许所有访问 + allow: + url-pattern: /druid/* + # 控制台管理用户名和密码 + login-username: ruoyi + login-password: 123456 + filter: + stat: + enabled: true + # 慢SQL记录 + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: true + wall: + config: + multi-statement-allow: true + # 资源信息 + messages: + # 国际化资源文件路径 + basename: i18n/messages + # profiles: + # active: druid + # 文件上传 + servlet: + multipart: + # 单个文件大小 + max-file-size: 10MB + # 设置总上传的文件大小 + max-request-size: 20MB + # 服务模块 + devtools: + restart: + # 热部署开关 + enabled: true + # redis 配置 + redis: + # 地址 + host: 192.168.100.168 + # 端口,默认为6379 + port: 6379 + # 数据库索引 + database: 2 + # 密码 + password: 123456 + # 连接超时时间 + timeout: 10s + lettuce: + pool: + # 连接池中的最小空闲连接 + min-idle: 0 + # 连接池中的最大空闲连接 + max-idle: 8 + # 连接池的最大数据库连接数 + max-active: 8 + # #连接池最大阻塞等待时间(使用负值表示没有限制) + max-wait: -1ms + +# token配置 +token: + # 令牌自定义标识 + header: Authorization + # 令牌密钥 + secret: abcdefghijklmnopqrstuvwxyz + # 令牌有效期(默认3600秒,即1小时) + expireTime: 3600 + +# MyBatisPlus配置 +mybatis-plus: + # 搜索指定包别名 + typeAliasesPackage: com.zzyl.**.domain + # 配置mapper的扫描,找到所有的mapper.xml映射文件 + mapperLocations: classpath*:mapper/**/*Mapper.xml + # 全局配置 + global-config: + db-config: + id-type: auto #id生成策略为自增 + configuration: + map-underscore-to-camel-case: true #字段与属性,自动转换为驼峰命名 + +# PageHelper分页插件 +pagehelper: + helperDialect: mysql + supportMethodsArguments: true + params: count=countSql + +# Swagger配置 +swagger: + # 是否开启swagger + enabled: true + # 请求前缀 + pathMapping: /dev-api + +# 防止XSS攻击 +xss: + # 过滤开关 + enabled: true + # 排除链接(多个用逗号分隔) + excludes: /system/notice + # 匹配链接 + urlPatterns: /system/*,/monitor/*,/tool/* + +# 阿里云OSS相关配置 +aliyun: + oss: + domain: oss-cn-beijing.aliyuncs.com + endpoint: https://oss-cn-beijing.aliyuncs.com + bucket-name: hzhm-mlgb2 + region: cn-hangzhou + accessKeyId: ${ALIYUN_OSS_ACCESS_KEY_ID:change_me_oss_key} + secretAccessKey: ${ALIYUN_OSS_SECRET_ACCESS_KEY:change_me_oss_secret} + +dept: + nursingId: 201 + +# 百度千帆大模型配置 +baidu: + accessKey: fONdLXB5zssLPU5PTIBRsyjl + secretKey: 9ntuGXNc482mKuOGy6pe1THSOzMB1oTs + qianfanModel: ERNIE-4.0-8K-Preview + +# 微信小程序配置 +wechat: + mini-program: + appId: wx3403f8301cf994c4 + secret: a0a813ae635736b8896ca0b065053c22 + +huaweicloud: + ak: 3CYUWXETDG50ZOSVR90M + sk: EUbQIqXAnpAEZoWVRolbrODeXEPBaqr5tWA5dRhv + #如果是上海一,请填写"cn-east-3";如果是北京四,请填写"cn-north-4"; + regionId: cn-east-3 + endpoint: 1a66a615d7.st1.iotda-app.cn-east-3.myhuaweicloud.com + projectId: 222ab8f0674849b090ce8007fb78f26a + #amqp相关配置 第二天课程接收设备数据使用 + host: 1a66a615d7.st1.iotda-app.cn-east-3.myhuaweicloud.com + accessKey: npr9vlTF + accessCode: zcm8SNenBCOFVaWlv3VtVh8yNGnRL4sz + queueName: DefaultQueue #默认无需改动 diff --git a/zzyl-admin/src/main/resources/application-prod.yml b/zzyl-admin/src/main/resources/application-prod.yml new file mode 100644 index 0000000..113048a --- /dev/null +++ b/zzyl-admin/src/main/resources/application-prod.yml @@ -0,0 +1,228 @@ +# 项目相关配置 +ruoyi: + # 名称 + name: zzyl + # 版本 + version: 3.8.8 + # 版权年份 + copyrightYear: 2024 + # 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath) + profile: ${RUOYI_PROFILE:/home/ruoyi/uploadPath} + # 获取ip地址开关 + addressEnabled: false + # 验证码类型 math 数字计算 char 字符验证 + captchaType: math + +# 开发环境配置 +server: + # 服务器的HTTP端口,默认为8080 + port: 9000 + servlet: + # 应用的访问路径 + context-path: / + tomcat: + # tomcat的URI编码 + uri-encoding: UTF-8 + # 连接数满后的排队数,默认为100 + accept-count: 1000 + threads: + # tomcat最大线程数,默认为200 + max: 800 + # Tomcat启动初始化的线程数,默认值10 + min-spare: 100 + +# 日志配置 +logging: + level: + com.zzyl: debug + org.springframework: warn + +# 用户配置 +user: + password: + # 密码最大错误次数 + maxRetryCount: 5 + # 密码锁定时间(默认10分钟) + lockTime: 10 + +# Spring配置 +# 数据源配置 +spring: + datasource: + type: com.alibaba.druid.pool.DruidDataSource + driverClassName: com.mysql.cj.jdbc.Driver + druid: + # 主库数据源 + master: + url: ${MYSQL_URL:jdbc:mysql://zzyl-mysql:3306/zzyl?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai} + username: ${MYSQL_USERNAME:zzyl} + password: ${MYSQL_PASSWORD:change_me_mysql_app} + # 从库数据源 + slave: + # 从数据源开关/默认关闭 + enabled: false + url: + username: + password: + # 初始连接数 + initialSize: 5 + # 最小连接池数量 + minIdle: 10 + # 最大连接池数量 + maxActive: 20 + # 配置获取连接等待超时的时间 + maxWait: 60000 + # 配置连接超时时间 + connectTimeout: 30000 + # 配置网络超时时间 + socketTimeout: 60000 + # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 + timeBetweenEvictionRunsMillis: 60000 + # 配置一个连接在池中最小生存的时间,单位是毫秒 + minEvictableIdleTimeMillis: 300000 + # 配置一个连接在池中最大生存的时间,单位是毫秒 + maxEvictableIdleTimeMillis: 900000 + # 配置检测连接是否有效 + validationQuery: SELECT 1 FROM DUAL + testWhileIdle: true + testOnBorrow: false + testOnReturn: false + webStatFilter: + enabled: true + statViewServlet: + enabled: true + # 设置白名单,不填则允许所有访问 + allow: + url-pattern: /druid/* + # 控制台管理用户名和密码 + login-username: ${DRUID_LOGIN_USERNAME:ruoyi} + login-password: ${DRUID_LOGIN_PASSWORD:change_me_druid} + filter: + stat: + enabled: true + # 慢SQL记录 + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: true + wall: + config: + multi-statement-allow: true + # 资源信息 + messages: + # 国际化资源文件路径 + basename: i18n/messages + # profiles: + # active: druid + # 文件上传 + servlet: + multipart: + # 单个文件大小 + max-file-size: 10MB + # 设置总上传的文件大小 + max-request-size: 20MB + # 服务模块 + devtools: + restart: + # 热部署开关 + enabled: true + # redis 配置 + redis: + # 地址 + host: ${REDIS_HOST:zzyl-redis} + # 端口,默认为6379 + port: ${REDIS_PORT:6379} + # 数据库索引 + database: ${REDIS_DATABASE:2} + # 密码 + password: ${REDIS_PASSWORD:change_me_redis} + # 连接超时时间 + timeout: 10s + lettuce: + pool: + # 连接池中的最小空闲连接 + min-idle: 0 + # 连接池中的最大空闲连接 + max-idle: 8 + # 连接池的最大数据库连接数 + max-active: 8 + # #连接池最大阻塞等待时间(使用负值表示没有限制) + max-wait: -1ms + +# token配置 +token: + # 令牌自定义标识 + header: Authorization + # 令牌密钥 + secret: ${TOKEN_SECRET:change_me_token_secret} + # 令牌有效期(默认3600秒,即1小时) + expireTime: ${TOKEN_EXPIRE_TIME:3600} + +# MyBatisPlus配置 +mybatis-plus: + # 搜索指定包别名 + typeAliasesPackage: com.zzyl.**.domain + # 配置mapper的扫描,找到所有的mapper.xml映射文件 + mapperLocations: classpath*:mapper/**/*Mapper.xml + # 全局配置 + global-config: + db-config: + id-type: auto #id生成策略为自增 + configuration: + map-underscore-to-camel-case: true #字段与属性,自动转换为驼峰命名 + +# PageHelper分页插件 +pagehelper: + helperDialect: mysql + supportMethodsArguments: true + params: count=countSql + +# Swagger配置 +swagger: + # 是否开启swagger + enabled: true + # 请求前缀 + pathMapping: /dev-api + +# 防止XSS攻击 +xss: + # 过滤开关 + enabled: true + # 排除链接(多个用逗号分隔) + excludes: /system/notice + # 匹配链接 + urlPatterns: /system/*,/monitor/*,/tool/* + +# 阿里云OSS相关配置 +aliyun: + oss: + domain: ${ALIYUN_OSS_DOMAIN:oss-cn-hangzhou.aliyuncs.com} + endpoint: ${ALIYUN_OSS_ENDPOINT:https://oss-cn-hangzhou.aliyuncs.com} + bucket-name: ${ALIYUN_OSS_BUCKET:change-me-bucket} + region: ${ALIYUN_OSS_REGION:cn-hangzhou} + accessKeyId: ${ALIYUN_OSS_ACCESS_KEY_ID:change_me_oss_key} + secretAccessKey: ${ALIYUN_OSS_SECRET_ACCESS_KEY:change_me_oss_secret} + +dept: + nursingId: ${DEPT_NURSING_ID:201} + +# 百度千帆大模型配置 +baidu: + accessKey: ${BAIDU_ACCESS_KEY:change_me_baidu_key} + secretKey: ${BAIDU_SECRET_KEY:change_me_baidu_secret} + qianfanModel: ${BAIDU_QIANFAN_MODEL:ERNIE-4.0-8K} + +wechat: + mini-program: + appId: ${WECHAT_MINI_PROGRAM_APP_ID:change_me_wechat_appid} + secret: ${WECHAT_MINI_PROGRAM_SECRET:change_me_wechat_secret} + +huaweicloud: + ak: ${HUAWEI_CLOUD_AK:change_me_huawei_ak} + sk: ${HUAWEI_CLOUD_SK:change_me_huawei_sk} + regionId: ${HUAWEI_CLOUD_REGION_ID:cn-east-3} + endpoint: ${HUAWEI_CLOUD_ENDPOINT:change_me_huawei_endpoint} + projectId: ${HUAWEI_CLOUD_PROJECT_ID:change_me_huawei_project_id} + host: ${HUAWEI_CLOUD_AMQP_HOST:change_me_huawei_amqp_host} + accessKey: ${HUAWEI_CLOUD_AMQP_ACCESS_KEY:change_me_huawei_amqp_access_key} + accessCode: ${HUAWEI_CLOUD_AMQP_ACCESS_CODE:change_me_huawei_amqp_access_code} + queueName: ${HUAWEI_CLOUD_AMQP_QUEUE_NAME:DefaultQueue} diff --git a/zzyl-admin/src/main/resources/application-test.yml b/zzyl-admin/src/main/resources/application-test.yml new file mode 100644 index 0000000..737cfea --- /dev/null +++ b/zzyl-admin/src/main/resources/application-test.yml @@ -0,0 +1,212 @@ +# 项目相关配置 +ruoyi: + # 名称 + name: zzyl + # 版本 + version: 3.8.8 + # 版权年份 + copyrightYear: 2024 + # 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath) + profile: D:/JAVAdevelop/ruoyi/uploadPath + # 获取ip地址开关 + addressEnabled: false + # 验证码类型 math 数字计算 char 字符验证 + captchaType: math + +# 开发环境配置 +server: + # 服务器的HTTP端口,默认为8080 + port: 9004 + servlet: + # 应用的访问路径 + context-path: / + tomcat: + # tomcat的URI编码 + uri-encoding: UTF-8 + # 连接数满后的排队数,默认为100 + accept-count: 1000 + threads: + # tomcat最大线程数,默认为200 + max: 800 + # Tomcat启动初始化的线程数,默认值10 + min-spare: 100 + +# 日志配置 +logging: + level: + com.zzyl: debug + org.springframework: warn + +# 用户配置 +user: + password: + # 密码最大错误次数 + maxRetryCount: 5 + # 密码锁定时间(默认10分钟) + lockTime: 10 + +# Spring配置 +# 数据源配置 +spring: + datasource: + type: com.alibaba.druid.pool.DruidDataSource + driverClassName: com.mysql.cj.jdbc.Driver + druid: + # 主库数据源 + master: + url: jdbc:mysql://192.168.100.168:3306/zzyl?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 + username: root + password: heima123 + # 从库数据源 + slave: + # 从数据源开关/默认关闭 + enabled: false + url: + username: + password: + # 初始连接数 + initialSize: 5 + # 最小连接池数量 + minIdle: 10 + # 最大连接池数量 + maxActive: 20 + # 配置获取连接等待超时的时间 + maxWait: 60000 + # 配置连接超时时间 + connectTimeout: 30000 + # 配置网络超时时间 + socketTimeout: 60000 + # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 + timeBetweenEvictionRunsMillis: 60000 + # 配置一个连接在池中最小生存的时间,单位是毫秒 + minEvictableIdleTimeMillis: 300000 + # 配置一个连接在池中最大生存的时间,单位是毫秒 + maxEvictableIdleTimeMillis: 900000 + # 配置检测连接是否有效 + validationQuery: SELECT 1 FROM DUAL + testWhileIdle: true + testOnBorrow: false + testOnReturn: false + webStatFilter: + enabled: true + statViewServlet: + enabled: true + # 设置白名单,不填则允许所有访问 + allow: + url-pattern: /druid/* + # 控制台管理用户名和密码 + login-username: ruoyi + login-password: 123456 + filter: + stat: + enabled: true + # 慢SQL记录 + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: true + wall: + config: + multi-statement-allow: true + # 资源信息 + messages: + # 国际化资源文件路径 + basename: i18n/messages + # profiles: + # active: druid + # 文件上传 + servlet: + multipart: + # 单个文件大小 + max-file-size: 10MB + # 设置总上传的文件大小 + max-request-size: 20MB + # 服务模块 + devtools: + restart: + # 热部署开关 + enabled: true + # redis 配置 + redis: + # 地址 + host: 192.168.100.168 + # 端口,默认为6379 + port: 6379 + # 数据库索引 + database: 2 + # 密码 + password: 123456 + # 连接超时时间 + timeout: 10s + lettuce: + pool: + # 连接池中的最小空闲连接 + min-idle: 0 + # 连接池中的最大空闲连接 + max-idle: 8 + # 连接池的最大数据库连接数 + max-active: 8 + # #连接池最大阻塞等待时间(使用负值表示没有限制) + max-wait: -1ms + +# token配置 +token: + # 令牌自定义标识 + header: Authorization + # 令牌密钥 + secret: abcdefghijklmnopqrstuvwxyz + # 令牌有效期(默认3600秒,即1小时) + expireTime: 3600 + +# MyBatisPlus配置 +mybatis-plus: + # 搜索指定包别名 + typeAliasesPackage: com.zzyl.**.domain + # 配置mapper的扫描,找到所有的mapper.xml映射文件 + mapperLocations: classpath*:mapper/**/*Mapper.xml + # 全局配置 + global-config: + db-config: + id-type: auto #id生成策略为自增 + configuration: + map-underscore-to-camel-case: true #字段与属性,自动转换为驼峰命名 + +# PageHelper分页插件 +pagehelper: + helperDialect: mysql + supportMethodsArguments: true + params: count=countSql + +# Swagger配置 +swagger: + # 是否开启swagger + enabled: true + # 请求前缀 + pathMapping: /dev-api + +# 防止XSS攻击 +xss: + # 过滤开关 + enabled: true + # 排除链接(多个用逗号分隔) + excludes: /system/notice + # 匹配链接 + urlPatterns: /system/*,/monitor/*,/tool/* + +# 阿里云OSS相关配置 +aliyun: + oss: + domain: oss-cn-beijing.aliyuncs.com + endpoint: https://oss-cn-beijing.aliyuncs.com + bucket-name: hzhm-mlgb2 + region: cn-hangzhou + accessKeyId: ${ALIYUN_OSS_ACCESS_KEY_ID:change_me_oss_key} + secretAccessKey: ${ALIYUN_OSS_SECRET_ACCESS_KEY:change_me_oss_secret} + +dept: + nursingId: 201 + +# 百度千帆大模型配置 +baidu: + accessKey: fONdLXB5zssLPU5PTIBRsyjl + secretKey: 9ntuGXNc482mKuOGy6pe1THSOzMB1oTs + qianfanModel: ERNIE-4.0-8K-Preview diff --git a/zzyl-admin/src/main/resources/application.yml b/zzyl-admin/src/main/resources/application.yml new file mode 100644 index 0000000..3d7808a --- /dev/null +++ b/zzyl-admin/src/main/resources/application.yml @@ -0,0 +1,3 @@ +spring: + profiles: + active: dev diff --git a/zzyl-admin/src/main/resources/banner.txt b/zzyl-admin/src/main/resources/banner.txt new file mode 100644 index 0000000..490473b --- /dev/null +++ b/zzyl-admin/src/main/resources/banner.txt @@ -0,0 +1,36 @@ +/* + + _oo0oo_ + o8888888o + 88" . "88 + (| -_- |) + 0\ = /0 + ___/`---'\___ + .' \\| | * '. + / \\||| : ||| * \ + / _||||| -:- |||||- \ + | | \\\ - * / | | + | \_| ''\---/'' |_/ | + \ .-\__ '-' ___/-. / + ___'. .' /--.--\ `. .'___ + ."" '< `.___\_<|>_/___.' >' "". + | | : `- \`.;`\ _ /`;.`/ - ` : | | + \ \ `_. \_ __\ /__ _/ .-` / / + =====`-.____`.___ \_____/___.-`___.-'===== + `=---=' + + + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + 佛祖保佑 永不宕机 永无BUG + + 佛曰: + 写字楼里写字间,写字间里程序员; + 程序人员写程序,又拿程序换酒钱。 + 酒醒只在网上坐,酒醉还来网下眠; + 酒醉酒醒日复日,网上网下年复年。 + 但愿老死电脑间,不愿鞠躬老板前; + 奔驰宝马贵者趣,公交自行程序员。 + 别人笑我忒疯癫,我笑自己命太贱; + 不见满街漂亮妹,哪个归得程序员? + */ \ No newline at end of file diff --git a/zzyl-admin/src/main/resources/i18n/messages.properties b/zzyl-admin/src/main/resources/i18n/messages.properties new file mode 100644 index 0000000..93de005 --- /dev/null +++ b/zzyl-admin/src/main/resources/i18n/messages.properties @@ -0,0 +1,38 @@ +#错误消息 +not.null=* 必须填写 +user.jcaptcha.error=验证码错误 +user.jcaptcha.expire=验证码已失效 +user.not.exists=用户不存在/密码错误 +user.password.not.match=用户不存在/密码错误 +user.password.retry.limit.count=密码输入错误{0}次 +user.password.retry.limit.exceed=密码输入错误{0}次,帐户锁定{1}分钟 +user.password.delete=对不起,您的账号已被删除 +user.blocked=用户已封禁,请联系管理员 +role.blocked=角色已封禁,请联系管理员 +login.blocked=很遗憾,访问IP已被列入系统黑名单 +user.logout.success=退出成功 + +length.not.valid=长度必须在{min}到{max}个字符之间 + +user.username.not.valid=* 2到20个汉字、字母、数字或下划线组成,且必须以非数字开头 +user.password.not.valid=* 5-50个字符 + +user.email.not.valid=邮箱格式错误 +user.mobile.phone.number.not.valid=手机号格式错误 +user.login.success=登录成功 +user.register.success=注册成功 +user.notfound=请重新登录 +user.forcelogout=管理员强制退出,请重新登录 +user.unknown.error=未知错误,请重新登录 + +##文件上传消息 +upload.exceed.maxSize=上传的文件大小超出限制的文件大小!
允许的文件最大大小是:{0}MB! +upload.filename.exceed.length=上传的文件名最长{0}个字符 + +##权限 +no.permission=您没有数据的权限,请联系管理员添加权限 [{0}] +no.create.permission=您没有创建数据的权限,请联系管理员添加权限 [{0}] +no.update.permission=您没有修改数据的权限,请联系管理员添加权限 [{0}] +no.delete.permission=您没有删除数据的权限,请联系管理员添加权限 [{0}] +no.export.permission=您没有导出数据的权限,请联系管理员添加权限 [{0}] +no.view.permission=您没有查看数据的权限,请联系管理员添加权限 [{0}] diff --git a/zzyl-admin/src/main/resources/logback.xml b/zzyl-admin/src/main/resources/logback.xml new file mode 100644 index 0000000..b2d5998 --- /dev/null +++ b/zzyl-admin/src/main/resources/logback.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + ${log.pattern} + + + + + + ${log.path}/sys-info.log + + + + ${log.path}/sys-info.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + INFO + + ACCEPT + + DENY + + + + + ${log.path}/sys-error.log + + + + ${log.path}/sys-error.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + ERROR + + ACCEPT + + DENY + + + + + + ${log.path}/sys-user.log + + + ${log.path}/sys-user.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/zzyl-admin/src/main/resources/mybatis/mybatis-config.xml b/zzyl-admin/src/main/resources/mybatis/mybatis-config.xml new file mode 100644 index 0000000..ac47c03 --- /dev/null +++ b/zzyl-admin/src/main/resources/mybatis/mybatis-config.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + diff --git a/zzyl-admin/src/test/java/com/zzyl/WeChat/WeChatTest.java b/zzyl-admin/src/test/java/com/zzyl/WeChat/WeChatTest.java new file mode 100644 index 0000000..cf800d6 --- /dev/null +++ b/zzyl-admin/src/test/java/com/zzyl/WeChat/WeChatTest.java @@ -0,0 +1,34 @@ +package com.zzyl.WeChat; + +import com.zzyl.nursing.service.IWeChatService; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +/** + * TODO + * + * @author Zhy + * @version 1.0 + * @date 2025-03-03 20:22 + */ +@SpringBootTest +public class WeChatTest { + + @Autowired + private IWeChatService weChatService; + + @Test + public void testGetOpenId() { + String openId = weChatService.getOpenId("0d3Vnr000mDGOT1tnD300t9N5B4Vnr0c"); + System.out.println("openId = " + openId); + } + + @Test + public void testGetPhoneNumber(){ + String phoneNumber = weChatService.getPhoneNumber("e69c5492c8a32828cfcc797b1eeaecacb167cadf502fc3d089d675fb6493a829"); + + System.out.println("phoneNumber = " + phoneNumber); + } + +} diff --git a/zzyl-admin/src/test/java/com/zzyl/hwy/IoTDeviceTest.java b/zzyl-admin/src/test/java/com/zzyl/hwy/IoTDeviceTest.java new file mode 100644 index 0000000..9934d45 --- /dev/null +++ b/zzyl-admin/src/test/java/com/zzyl/hwy/IoTDeviceTest.java @@ -0,0 +1,36 @@ +package com.zzyl.hwy; + +import com.huaweicloud.sdk.iotda.v5.IoTDAClient; +import com.huaweicloud.sdk.iotda.v5.model.ListProductsRequest; +import com.huaweicloud.sdk.iotda.v5.model.ListProductsResponse; +import com.huaweicloud.sdk.iotda.v5.model.Page; +import com.huaweicloud.sdk.iotda.v5.model.ProductSummary; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import java.util.List; + +@SpringBootTest +public class IoTDeviceTest { + + + @Autowired + private IoTDAClient client; + + /** + * 查询公共实例下的所有产品 + * + * @throws Exception + */ + @Test + public void selectProduceList() throws Exception { + + ListProductsRequest listProductsRequest = new ListProductsRequest(); + listProductsRequest.setLimit(50); + ListProductsResponse response = client.listProducts(listProductsRequest); + List products = response.getProducts(); + System.out.println(products); + } + +} \ No newline at end of file diff --git a/zzyl-admin/src/test/java/com/zzyl/qf/AIModelTest.java b/zzyl-admin/src/test/java/com/zzyl/qf/AIModelTest.java new file mode 100644 index 0000000..d98b2e3 --- /dev/null +++ b/zzyl-admin/src/test/java/com/zzyl/qf/AIModelTest.java @@ -0,0 +1,39 @@ +package com.zzyl.qf; + +import com.baidubce.qianfan.Qianfan; +import com.baidubce.qianfan.core.auth.Auth; +import com.baidubce.qianfan.model.chat.ChatResponse; + +/** + * TODO + * + * @Author: Zhy + * @Date: 2025-02-28 14:12 + * @Version: 1.0 + */ +public class AIModelTest { + + public static void main(String[] args) { + /* + * 第一个参数:认证类型,固定选择 Auth.TYPE_OAUTH + * 第二个参数:accessKeyId,从百度云控制台创建的应用里可以找到 + * 第三个参数:accessKeySecret,从百度云控制台创建的应用里可以找到 + */ + Qianfan qianfan = new Qianfan( + Auth.TYPE_OAUTH, + "fONdLXB5zssLPU5PTIBRsyjl", + "9ntuGXNc482mKuOGy6pe1THSOzMB1oTs" + ); + ChatResponse response = qianfan.chatCompletion() + .model("ERNIE-4.0-8K-Preview") + .temperature(0.6) + .maxOutputTokens(2000) + .responseFormat("json_object") + .addMessage("user", "你能帮我分析一份完整的体检报告吗?") + .execute(); + + String result = response.getResult(); + System.out.println(result); + } + +} diff --git a/zzyl-admin/src/test/java/com/zzyl/redis/RedisTemplateTest.java b/zzyl-admin/src/test/java/com/zzyl/redis/RedisTemplateTest.java new file mode 100644 index 0000000..90ac33d --- /dev/null +++ b/zzyl-admin/src/test/java/com/zzyl/redis/RedisTemplateTest.java @@ -0,0 +1,179 @@ +package com.zzyl.redis; + +import cn.hutool.core.thread.ThreadUtil; +import com.zzyl.common.utils.DateUtils; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.SetOperations; +import org.springframework.data.redis.core.ValueOperations; +import org.springframework.data.redis.core.ZSetOperations; + +import java.time.Duration; +import java.util.*; +import java.util.concurrent.TimeUnit; + +/** + * Redis 的 java + * + * @Author: Zhy + * @Date: 2025-02-27 10:56 + * @Version: 1.0 + */ +@SpringBootTest +public class RedisTemplateTest { + + @Autowired + private RedisTemplate redisTemplate; + + /** + * String 类型 + */ + @Test + public void testString() { + ValueOperations valueOperations = redisTemplate.opsForValue(); + + // 设置值 + valueOperations.set("name", "Jack"); + // 设置值并设置过期时间,单位:分钟 + valueOperations.set("age", 25, 2, TimeUnit.SECONDS); + // 设置值,如果不存在则设置 + valueOperations.setIfAbsent("gender", 1); + valueOperations.setIfAbsent("gender", 2); + + // 获取值 + String name = (String) valueOperations.get("name"); + System.out.println("name = " + name); + System.out.println("valueOperations.get(\"age\") = " + valueOperations.get("age")); + ThreadUtil.sleep(2500); + System.out.println("valueOperations.get(\"age\") = " + valueOperations.get("age")); + + // 自增值 + valueOperations.set("num", 20); + valueOperations.increment("num"); + System.out.println("valueOperations.get(\"num\") = " + valueOperations.get("num")); + valueOperations.increment("num", 5); + System.out.println("valueOperations.get(\"num\") = " + valueOperations.get("num")); + + // 删除值 + redisTemplate.delete("name"); + redisTemplate.delete("age"); + } + + /** + * Hash 类型 + */ + @Test + public void testHash() { + HashMap userMap = new HashMap<>(); + userMap.put("age", 25); + userMap.put("gender", 1); + userMap.put("birthday", DateUtils.getNowDate()); + + // 保存数据 + redisTemplate.opsForHash().put("user", "name", "Tom"); + redisTemplate.opsForHash().putAll("user", userMap); + + // 获取数据 + Object birthday = redisTemplate.opsForHash().get("user", "birthday"); + System.out.println("birthday = " + birthday); + + // 获取所有字段 + Set set = redisTemplate.opsForHash().keys("user"); + System.out.println("set = " + set); + // 获取所有值 + List user = redisTemplate.opsForHash().values("user"); + System.out.println("user = " + user); + // 获取所有键值对 + Map map = redisTemplate.opsForHash().entries("user"); + System.out.println("map = " + map); + } + + /** + * List 类型 + */ + @Test + public void testList() { + // 保存数据 + redisTemplate.opsForList().leftPush("list", "a"); + redisTemplate.opsForList().leftPushAll("list", "b", "c"); + redisTemplate.opsForList().rightPush("list", "d"); + + // 获取数据 + List users = redisTemplate.opsForList().range("list", 0, -1); + System.out.println("users = " + users); + // 获取指定索引的数据 + Object user = redisTemplate.opsForList().index("list", 2); + System.out.println("user = " + user); + // 弹出数据 + Object n = redisTemplate.opsForList().leftPop("list"); + System.out.println("n = " + n); + } + + /** + * set 类型 + */ + @Test + public void testSet() { + SetOperations setOperations = redisTemplate.opsForSet(); + // 保存数据 + setOperations.add("hobbies", "java", "C", "C#", "swim"); + Set hobbies = setOperations.members("hobbies"); + System.out.println("hobbies = " + hobbies); + + // 元素是否存在 + System.out.println(setOperations.isMember("hobbies", "java")); + System.out.println(setOperations.isMember("hobbies", "C++")); + // 随机弹出元素 + System.out.println(setOperations.pop("hobbies")); + // 大小 + System.out.println(setOperations.size("hobbies")); + + setOperations.add("h1", "java", "C", "C#", "swim", "html"); + setOperations.add("h2", "java", "C++", "C#", "swim", "PHP"); + // 交集 + System.out.println(setOperations.intersect("h1", "h2")); + // 并集 + setOperations.unionAndStore("h1", "h2", "h3"); + System.out.println(setOperations.members("h3")); + // 差集 + System.out.println(setOperations.difference("h2", "h1")); + } + + /** + * zSet 类型 + */ + @Test + public void testZSet() { + ZSetOperations zSetOperations = redisTemplate.opsForZSet(); + // 保存数据 + zSetOperations.add("course", "java", 80); + zSetOperations.add("course", "C", 90); + zSetOperations.add("course", "C#", 70); + zSetOperations.add("course", "html", 95); + + // 获取数据 + Set course = zSetOperations.reverseRange("course", 0, 2); + assert course != null; + course.forEach(System.out::println); + } + + /** + * 通用方法 + */ + @Test + public void testCommon() { + // 输出所有 key + Objects.requireNonNull(redisTemplate.keys("*")).forEach(System.out::println); + // 设置过期时间,单位:分钟 + redisTemplate.expire("course", Duration.ofMinutes(10)); + // 输出 key 类型 + System.out.println(redisTemplate.type("hobbies")); + // 是否存在 + System.out.println(redisTemplate.hasKey("hobbies")); + // 删除 key + System.out.println(redisTemplate.delete("num")); + } + +} diff --git a/zzyl-admin/src/test/java/com/zzyl/utils/PDFUtilTest.java b/zzyl-admin/src/test/java/com/zzyl/utils/PDFUtilTest.java new file mode 100644 index 0000000..d23882e --- /dev/null +++ b/zzyl-admin/src/test/java/com/zzyl/utils/PDFUtilTest.java @@ -0,0 +1,27 @@ +package com.zzyl.utils; + +import com.zzyl.common.utils.PDFUtil; +import org.junit.jupiter.api.Test; + +import java.io.*; + +/** + * TODO + * + * @Author: Zhy + * @Date: 2025-02-28 11:50 + * @Version: 1.0 + */ +public class PDFUtilTest { + + @Test + public void testPdfToString() throws Exception { + + FileInputStream fileInputStream = new FileInputStream( + "D:\\JAVAdevelop\\hmClass\\课程\\中州养老\\素材\\体检报告样例\\体检报告-刘爱国-男-69岁.pdf"); + + String result = PDFUtil.pdfToString(fileInputStream); + System.out.println(result); + } + +} diff --git a/zzyl-common/pom.xml b/zzyl-common/pom.xml new file mode 100644 index 0000000..12c2b2b --- /dev/null +++ b/zzyl-common/pom.xml @@ -0,0 +1,170 @@ + + + + zzyl + com.zzyl + 3.8.8 + + 4.0.0 + + zzyl-common + + + common通用工具 + + + + + + + org.springframework + spring-context-support + + + + + org.springframework + spring-web + + + + + org.springframework.boot + spring-boot-starter-security + + + + + com.github.pagehelper + pagehelper-spring-boot-starter + + + + + org.springframework.boot + spring-boot-starter-validation + + + + + org.apache.commons + commons-lang3 + + + + + com.fasterxml.jackson.core + jackson-databind + + + + + com.alibaba.fastjson2 + fastjson2 + + + + + commons-io + commons-io + + + + + org.apache.poi + poi-ooxml + + + + + org.yaml + snakeyaml + + + + + io.jsonwebtoken + jjwt + + + + + javax.xml.bind + jaxb-api + + + + + org.springframework.boot + spring-boot-starter-data-redis + + + + + org.apache.commons + commons-pool2 + + + + + eu.bitwalker + UserAgentUtils + + + + + javax.servlet + javax.servlet-api + + + + + com.github.xiaoymin + knife4j-spring-boot-starter + 3.0.3 + + + + + org.projectlombok + lombok + + + + + com.baomidou + mybatis-plus-boot-starter + + + com.baomidou + mybatis-plus-annotation + + + + + cn.hutool + hutool-all + + + + + org.apache.pdfbox + pdfbox + + + + + com.baidubce + qianfan + + + + org.springframework.boot + spring-boot-starter-test + + + + + \ No newline at end of file diff --git a/zzyl-common/src/main/java/com/zzyl/common/ai/AIModelInvoker.java b/zzyl-common/src/main/java/com/zzyl/common/ai/AIModelInvoker.java new file mode 100644 index 0000000..ff78c05 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/ai/AIModelInvoker.java @@ -0,0 +1,47 @@ +package com.zzyl.common.ai; + +import com.baidubce.qianfan.Qianfan; +import com.baidubce.qianfan.core.auth.Auth; +import com.baidubce.qianfan.model.chat.ChatResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +/** + * 集成百度千帆大模型 + * + * @Author: Zhy + * @Date: 2025-02-28 16:39 + * @Version: 1.0 + */ +@Component +@RequiredArgsConstructor +public class AIModelInvoker { + + private final BaiduAIProperties baiduAIProperties; + + /** + * 调用百度智能对话API + * + * @return: 返回的文本结果 + * @param: prompt 输入的提示文本 + */ + public String qianfanInvoker(String prompt) { + /* + * 第一个参数:认证类型,固定选择 Auth.TYPE_OAUTH + * 第二个参数:accessKeyId,从百度云控制台创建的应用里可以找到 + * 第三个参数:accessKeySecret,从百度云控制台创建的应用里可以找到 + */ + Qianfan qianfan = new Qianfan(Auth.TYPE_OAUTH, baiduAIProperties.getAccessKey(), baiduAIProperties.getSecretKey()); + + ChatResponse response = qianfan.chatCompletion() + .model(baiduAIProperties.getQianfanModel()) + .temperature(0.6) + .maxOutputTokens(2000) + .responseFormat("json_object") + .addMessage("user", prompt) + .execute(); + + return response.getResult(); + } + +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/ai/BaiduAIProperties.java b/zzyl-common/src/main/java/com/zzyl/common/ai/BaiduAIProperties.java new file mode 100644 index 0000000..5f2aac1 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/ai/BaiduAIProperties.java @@ -0,0 +1,23 @@ +package com.zzyl.common.ai; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * 百度千帆大模型配置 + * + * @Author: Zhy + * @Date: 2025-02-28 16:38 + * @Version: 1.0 + */ +@Data +@Component +@ConfigurationProperties(prefix = "baidu") +public class BaiduAIProperties { + + private String accessKey; + private String secretKey; + private String qianfanModel; + +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/annotation/Anonymous.java b/zzyl-common/src/main/java/com/zzyl/common/annotation/Anonymous.java new file mode 100644 index 0000000..ef01286 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/annotation/Anonymous.java @@ -0,0 +1,19 @@ +package com.zzyl.common.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 匿名访问不鉴权注解 + * + * @author ruoyi + */ +@Target({ ElementType.METHOD, ElementType.TYPE }) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface Anonymous +{ +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/annotation/DataScope.java b/zzyl-common/src/main/java/com/zzyl/common/annotation/DataScope.java new file mode 100644 index 0000000..f92076f --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/annotation/DataScope.java @@ -0,0 +1,33 @@ +package com.zzyl.common.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 数据权限过滤注解 + * + * @author ruoyi + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface DataScope +{ + /** + * 部门表的别名 + */ + public String deptAlias() default ""; + + /** + * 用户表的别名 + */ + public String userAlias() default ""; + + /** + * 权限字符(用于多个角色匹配符合要求的权限)默认根据权限注解@ss获取,多个权限用逗号分隔开来 + */ + public String permission() default ""; +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/annotation/DataSource.java b/zzyl-common/src/main/java/com/zzyl/common/annotation/DataSource.java new file mode 100644 index 0000000..0b0d77a --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/annotation/DataSource.java @@ -0,0 +1,28 @@ +package com.zzyl.common.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import com.zzyl.common.enums.DataSourceType; + +/** + * 自定义多数据源切换注解 + * + * 优先级:先方法,后类,如果方法覆盖了类上的数据源类型,以方法的为准,否则以类上的为准 + * + * @author ruoyi + */ +@Target({ ElementType.METHOD, ElementType.TYPE }) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Inherited +public @interface DataSource +{ + /** + * 切换数据源名称 + */ + public DataSourceType value() default DataSourceType.MASTER; +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/annotation/Excel.java b/zzyl-common/src/main/java/com/zzyl/common/annotation/Excel.java new file mode 100644 index 0000000..82ec981 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/annotation/Excel.java @@ -0,0 +1,198 @@ +package com.zzyl.common.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.math.RoundingMode; + +import org.apache.poi.ss.usermodel.HorizontalAlignment; +import org.apache.poi.ss.usermodel.IndexedColors; +import com.zzyl.common.utils.poi.ExcelHandlerAdapter; + +/** + * 自定义导出Excel数据注解 + * + * @author ruoyi + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface Excel +{ + /** + * 导出时在excel中排序 + */ + public int sort() default Integer.MAX_VALUE; + + /** + * 导出到Excel中的名字. + */ + public String name() default ""; + + /** + * 日期格式, 如: yyyy-MM-dd + */ + public String dateFormat() default ""; + + /** + * 如果是字典类型,请设置字典的type值 (如: sys_user_sex) + */ + public String dictType() default ""; + + /** + * 读取内容转表达式 (如: 0=男,1=女,2=未知) + */ + public String readConverterExp() default ""; + + /** + * 分隔符,读取字符串组内容 + */ + public String separator() default ","; + + /** + * BigDecimal 精度 默认:-1(默认不开启BigDecimal格式化) + */ + public int scale() default -1; + + /** + * BigDecimal 舍入规则 默认:BigDecimal.ROUND_HALF_EVEN + */ + public RoundingMode roundingMode() default RoundingMode.HALF_EVEN; + + /** + * 导出时在excel中每个列的高度 + */ + public double height() default 14; + + /** + * 导出时在excel中每个列的宽度 + */ + public double width() default 16; + + /** + * 文字后缀,如% 90 变成90% + */ + public String suffix() default ""; + + /** + * 当值为空时,字段的默认值 + */ + public String defaultValue() default ""; + + /** + * 提示信息 + */ + public String prompt() default ""; + + /** + * 是否允许内容换行 + */ + public boolean wrapText() default false; + + /** + * 设置只能选择不能输入的列内容. + */ + public String[] combo() default {}; + + /** + * 是否从字典读数据到combo,默认不读取,如读取需要设置dictType注解. + */ + public boolean comboReadDict() default false; + + /** + * 是否需要纵向合并单元格,应对需求:含有list集合单元格) + */ + public boolean needMerge() default false; + + /** + * 是否导出数据,应对需求:有时我们需要导出一份模板,这是标题需要但内容需要用户手工填写. + */ + public boolean isExport() default true; + + /** + * 另一个类中的属性名称,支持多级获取,以小数点隔开 + */ + public String targetAttr() default ""; + + /** + * 是否自动统计数据,在最后追加一行统计数据总和 + */ + public boolean isStatistics() default false; + + /** + * 导出类型(0数字 1字符串 2图片) + */ + public ColumnType cellType() default ColumnType.STRING; + + /** + * 导出列头背景颜色 + */ + public IndexedColors headerBackgroundColor() default IndexedColors.GREY_50_PERCENT; + + /** + * 导出列头字体颜色 + */ + public IndexedColors headerColor() default IndexedColors.WHITE; + + /** + * 导出单元格背景颜色 + */ + public IndexedColors backgroundColor() default IndexedColors.WHITE; + + /** + * 导出单元格字体颜色 + */ + public IndexedColors color() default IndexedColors.BLACK; + + /** + * 导出字段对齐方式 + */ + public HorizontalAlignment align() default HorizontalAlignment.CENTER; + + /** + * 自定义数据处理器 + */ + public Class handler() default ExcelHandlerAdapter.class; + + /** + * 自定义数据处理器参数 + */ + public String[] args() default {}; + + /** + * 字段类型(0:导出导入;1:仅导出;2:仅导入) + */ + Type type() default Type.ALL; + + public enum Type + { + ALL(0), EXPORT(1), IMPORT(2); + private final int value; + + Type(int value) + { + this.value = value; + } + + public int value() + { + return this.value; + } + } + + public enum ColumnType + { + NUMERIC(0), STRING(1), IMAGE(2), TEXT(3); + private final int value; + + ColumnType(int value) + { + this.value = value; + } + + public int value() + { + return this.value; + } + } +} \ No newline at end of file diff --git a/zzyl-common/src/main/java/com/zzyl/common/annotation/Excels.java b/zzyl-common/src/main/java/com/zzyl/common/annotation/Excels.java new file mode 100644 index 0000000..1225c93 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/annotation/Excels.java @@ -0,0 +1,18 @@ +package com.zzyl.common.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Excel注解集 + * + * @author ruoyi + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Excels +{ + public Excel[] value(); +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/annotation/Log.java b/zzyl-common/src/main/java/com/zzyl/common/annotation/Log.java new file mode 100644 index 0000000..0803c0d --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/annotation/Log.java @@ -0,0 +1,51 @@ +package com.zzyl.common.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import com.zzyl.common.enums.BusinessType; +import com.zzyl.common.enums.OperatorType; + +/** + * 自定义操作日志记录注解 + * + * @author ruoyi + * + */ +@Target({ ElementType.PARAMETER, ElementType.METHOD }) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface Log +{ + /** + * 模块 + */ + public String title() default ""; + + /** + * 功能 + */ + public BusinessType businessType() default BusinessType.OTHER; + + /** + * 操作人类别 + */ + public OperatorType operatorType() default OperatorType.MANAGE; + + /** + * 是否保存请求的参数 + */ + public boolean isSaveRequestData() default true; + + /** + * 是否保存响应的参数 + */ + public boolean isSaveResponseData() default true; + + /** + * 排除指定的请求参数 + */ + public String[] excludeParamNames() default {}; +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/annotation/RateLimiter.java b/zzyl-common/src/main/java/com/zzyl/common/annotation/RateLimiter.java new file mode 100644 index 0000000..a2e1579 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/annotation/RateLimiter.java @@ -0,0 +1,40 @@ +package com.zzyl.common.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import com.zzyl.common.constant.CacheConstants; +import com.zzyl.common.enums.LimitType; + +/** + * 限流注解 + * + * @author ruoyi + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface RateLimiter +{ + /** + * 限流key + */ + public String key() default CacheConstants.RATE_LIMIT_KEY; + + /** + * 限流时间,单位秒 + */ + public int time() default 60; + + /** + * 限流次数 + */ + public int count() default 100; + + /** + * 限流类型 + */ + public LimitType limitType() default LimitType.DEFAULT; +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/annotation/RepeatSubmit.java b/zzyl-common/src/main/java/com/zzyl/common/annotation/RepeatSubmit.java new file mode 100644 index 0000000..d911069 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/annotation/RepeatSubmit.java @@ -0,0 +1,31 @@ +package com.zzyl.common.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 自定义注解防止表单重复提交 + * + * @author ruoyi + * + */ +@Inherited +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface RepeatSubmit +{ + /** + * 间隔时间(ms),小于此时间视为重复提交 + */ + public int interval() default 5000; + + /** + * 提示消息 + */ + public String message() default "不允许重复提交,请稍候再试"; +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/annotation/Sensitive.java b/zzyl-common/src/main/java/com/zzyl/common/annotation/Sensitive.java new file mode 100644 index 0000000..0f86e75 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/annotation/Sensitive.java @@ -0,0 +1,24 @@ +package com.zzyl.common.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.zzyl.common.config.serializer.SensitiveJsonSerializer; +import com.zzyl.common.enums.DesensitizedType; + +/** + * 数据脱敏注解 + * + * @author ruoyi + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +@JacksonAnnotationsInside +@JsonSerialize(using = SensitiveJsonSerializer.class) +public @interface Sensitive +{ + DesensitizedType desensitizedType(); +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/config/RuoYiConfig.java b/zzyl-common/src/main/java/com/zzyl/common/config/RuoYiConfig.java new file mode 100644 index 0000000..e3c6f0b --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/config/RuoYiConfig.java @@ -0,0 +1,122 @@ +package com.zzyl.common.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * 读取项目相关配置 + * + * @author ruoyi + */ +@Component +@ConfigurationProperties(prefix = "ruoyi") +public class RuoYiConfig +{ + /** 项目名称 */ + private String name; + + /** 版本 */ + private String version; + + /** 版权年份 */ + private String copyrightYear; + + /** 上传路径 */ + private static String profile; + + /** 获取地址开关 */ + private static boolean addressEnabled; + + /** 验证码类型 */ + private static String captchaType; + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public String getVersion() + { + return version; + } + + public void setVersion(String version) + { + this.version = version; + } + + public String getCopyrightYear() + { + return copyrightYear; + } + + public void setCopyrightYear(String copyrightYear) + { + this.copyrightYear = copyrightYear; + } + + public static String getProfile() + { + return profile; + } + + public void setProfile(String profile) + { + RuoYiConfig.profile = profile; + } + + public static boolean isAddressEnabled() + { + return addressEnabled; + } + + public void setAddressEnabled(boolean addressEnabled) + { + RuoYiConfig.addressEnabled = addressEnabled; + } + + public static String getCaptchaType() { + return captchaType; + } + + public void setCaptchaType(String captchaType) { + RuoYiConfig.captchaType = captchaType; + } + + /** + * 获取导入上传路径 + */ + public static String getImportPath() + { + return getProfile() + "/import"; + } + + /** + * 获取头像上传路径 + */ + public static String getAvatarPath() + { + return getProfile() + "/avatar"; + } + + /** + * 获取下载路径 + */ + public static String getDownloadPath() + { + return getProfile() + "/download/"; + } + + /** + * 获取上传路径 + */ + public static String getUploadPath() + { + return getProfile() + "/upload"; + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/config/serializer/SensitiveJsonSerializer.java b/zzyl-common/src/main/java/com/zzyl/common/config/serializer/SensitiveJsonSerializer.java new file mode 100644 index 0000000..9893b06 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/config/serializer/SensitiveJsonSerializer.java @@ -0,0 +1,67 @@ +package com.zzyl.common.config.serializer; + +import java.io.IOException; +import java.util.Objects; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.BeanProperty; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.ContextualSerializer; +import com.zzyl.common.annotation.Sensitive; +import com.zzyl.common.core.domain.model.LoginUser; +import com.zzyl.common.enums.DesensitizedType; +import com.zzyl.common.utils.SecurityUtils; + +/** + * 数据脱敏序列化过滤 + * + * @author ruoyi + */ +public class SensitiveJsonSerializer extends JsonSerializer implements ContextualSerializer +{ + private DesensitizedType desensitizedType; + + @Override + public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException + { + if (desensitization()) + { + gen.writeString(desensitizedType.desensitizer().apply(value)); + } + else + { + gen.writeString(value); + } + } + + @Override + public JsonSerializer createContextual(SerializerProvider prov, BeanProperty property) + throws JsonMappingException + { + Sensitive annotation = property.getAnnotation(Sensitive.class); + if (Objects.nonNull(annotation) && Objects.equals(String.class, property.getType().getRawClass())) + { + this.desensitizedType = annotation.desensitizedType(); + return this; + } + return prov.findValueSerializer(property.getType(), property); + } + + /** + * 是否需要脱敏处理 + */ + private boolean desensitization() + { + try + { + LoginUser securityUser = SecurityUtils.getLoginUser(); + // 管理员不脱敏 + return !securityUser.getUser().isAdmin(); + } + catch (Exception e) + { + return true; + } + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/constant/CacheConstants.java b/zzyl-common/src/main/java/com/zzyl/common/constant/CacheConstants.java new file mode 100644 index 0000000..dfe1f3c --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/constant/CacheConstants.java @@ -0,0 +1,54 @@ +package com.zzyl.common.constant; + +/** + * 缓存的key 常量 + * + * @author ruoyi + */ +public class CacheConstants { + /** 登录用户 redis key */ + public static final String LOGIN_TOKEN_KEY = "login_tokens:"; + + /** 验证码 redis key */ + public static final String CAPTCHA_CODE_KEY = "captcha_codes:"; + + /** 参数管理 cache key */ + public static final String SYS_CONFIG_KEY = "sys_config:"; + + /** 字典管理 cache key */ + public static final String SYS_DICT_KEY = "sys_dict:"; + + /** 防重提交 redis key */ + public static final String REPEAT_SUBMIT_KEY = "repeat_submit:"; + + /** 限流 redis key */ + public static final String RATE_LIMIT_KEY = "rate_limit:"; + + /** 登录账户密码错误次数 redis key */ + public static final String PWD_ERR_CNT_KEY = "pwd_err_cnt:"; + + /** 护理等级 redis key */ + public static final String NURSING_LEVEL_ENABLE_KEY = "nursing_level_enable:all"; + + /** 护理计划 redis key */ + public static final String NURSING_PLAN_ENABLE_KEY = "nursing_plan_enable:all"; + + /** 护理项目 redis key */ + public static final String NURSING_PROJECT_ENABLE_KEY = "nursing_project_enable:all"; + + /** 体检报告 redis key */ + public static final String HEALTH_REPORT_KEY = "health:report:"; + + /** IOT 设备 redis key */ + public static final String IOT_ALL_PRODUCT = "iot:all_product"; + + /** IOT 设备 redis key */ + public static final String IOT_DEVICE_LAST_DATA = "iot:device_last_data:"; + + /** 报警规则联系触发次数 */ + public static final String ALERT_TRIGGER_COUNT_PREFIX = "iot:alert_trigger_count:rule_"; + + /** 报警规则沉默周期 */ + public static final String ALERT_SILENT_PREFIX = "iot:alert_silent:rule_"; + +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/constant/Constants.java b/zzyl-common/src/main/java/com/zzyl/common/constant/Constants.java new file mode 100644 index 0000000..b035929 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/constant/Constants.java @@ -0,0 +1,173 @@ +package com.zzyl.common.constant; + +import java.util.Locale; +import io.jsonwebtoken.Claims; + +/** + * 通用常量信息 + * + * @author ruoyi + */ +public class Constants +{ + /** + * UTF-8 字符集 + */ + public static final String UTF8 = "UTF-8"; + + /** + * GBK 字符集 + */ + public static final String GBK = "GBK"; + + /** + * 系统语言 + */ + public static final Locale DEFAULT_LOCALE = Locale.SIMPLIFIED_CHINESE; + + /** + * www主域 + */ + public static final String WWW = "www."; + + /** + * http请求 + */ + public static final String HTTP = "http://"; + + /** + * https请求 + */ + public static final String HTTPS = "https://"; + + /** + * 通用成功标识 + */ + public static final String SUCCESS = "0"; + + /** + * 通用失败标识 + */ + public static final String FAIL = "1"; + + /** + * 登录成功 + */ + public static final String LOGIN_SUCCESS = "Success"; + + /** + * 注销 + */ + public static final String LOGOUT = "Logout"; + + /** + * 注册 + */ + public static final String REGISTER = "Register"; + + /** + * 登录失败 + */ + public static final String LOGIN_FAIL = "Error"; + + /** + * 所有权限标识 + */ + public static final String ALL_PERMISSION = "*:*:*"; + + /** + * 管理员角色权限标识 + */ + public static final String SUPER_ADMIN = "admin"; + + /** + * 角色权限分隔符 + */ + public static final String ROLE_DELIMETER = ","; + + /** + * 权限标识分隔符 + */ + public static final String PERMISSION_DELIMETER = ","; + + /** + * 验证码有效期(分钟) + */ + public static final Integer CAPTCHA_EXPIRATION = 2; + + /** + * 令牌 + */ + public static final String TOKEN = "token"; + + /** + * 令牌前缀 + */ + public static final String TOKEN_PREFIX = "Bearer "; + + /** + * 令牌前缀 + */ + public static final String LOGIN_USER_KEY = "login_user_key"; + + /** + * 用户ID + */ + public static final String JWT_USERID = "userid"; + + /** + * 用户名称 + */ + public static final String JWT_USERNAME = Claims.SUBJECT; + + /** + * 用户头像 + */ + public static final String JWT_AVATAR = "avatar"; + + /** + * 创建时间 + */ + public static final String JWT_CREATED = "created"; + + /** + * 用户权限 + */ + public static final String JWT_AUTHORITIES = "authorities"; + + /** + * 资源映射路径 前缀 + */ + public static final String RESOURCE_PREFIX = "/profile"; + + /** + * RMI 远程方法调用 + */ + public static final String LOOKUP_RMI = "rmi:"; + + /** + * LDAP 远程方法调用 + */ + public static final String LOOKUP_LDAP = "ldap:"; + + /** + * LDAPS 远程方法调用 + */ + public static final String LOOKUP_LDAPS = "ldaps:"; + + /** + * 自动识别json对象白名单配置(仅允许解析的包名,范围越小越安全) + */ + public static final String[] JSON_WHITELIST_STR = { "org.springframework", "com.zzyl" }; + + /** + * 定时任务白名单配置(仅允许访问的包名,如其他需要可以自行添加) + */ + public static final String[] JOB_WHITELIST_STR = { "com.zzyl.quartz.task", "com.zzyl.nursing.job" }; + + /** + * 定时任务违规的字符 + */ + public static final String[] JOB_ERROR_STR = { "java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml", + "org.springframework", "org.apache", "com.zzyl.common.utils.file", "com.zzyl.common.config", "com.zzyl.generator" }; +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/constant/GenConstants.java b/zzyl-common/src/main/java/com/zzyl/common/constant/GenConstants.java new file mode 100644 index 0000000..e48bf6c --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/constant/GenConstants.java @@ -0,0 +1,126 @@ +package com.zzyl.common.constant; + +/** + * 代码生成通用常量 + * + * @author ruoyi + */ +public class GenConstants +{ + /** 单表(增删改查) */ + public static final String TPL_CRUD = "crud"; + + /** 树表(增删改查) */ + public static final String TPL_TREE = "tree"; + + /** 主子表(增删改查) */ + public static final String TPL_SUB = "sub"; + + /** 树编码字段 */ + public static final String TREE_CODE = "treeCode"; + + /** 树父编码字段 */ + public static final String TREE_PARENT_CODE = "treeParentCode"; + + /** 树名称字段 */ + public static final String TREE_NAME = "treeName"; + + /** 上级菜单ID字段 */ + public static final String PARENT_MENU_ID = "parentMenuId"; + + /** 上级菜单名称字段 */ + public static final String PARENT_MENU_NAME = "parentMenuName"; + + /** 数据库字符串类型 */ + public static final String[] COLUMNTYPE_STR = { "char", "varchar", "nvarchar", "varchar2" }; + + /** 数据库文本类型 */ + public static final String[] COLUMNTYPE_TEXT = { "tinytext", "text", "mediumtext", "longtext" }; + + /** 数据库时间类型 */ + public static final String[] COLUMNTYPE_TIME = { "datetime", "time", "date", "timestamp" }; + + /** 数据库数字类型 */ + public static final String[] COLUMNTYPE_NUMBER = { "tinyint", "smallint", "mediumint", "int", "number", "integer", + "bit", "bigint", "float", "double", "decimal" }; + + /** 页面不需要编辑字段 */ + public static final String[] COLUMNNAME_NOT_EDIT = { "id", "create_by", "create_time", "del_flag" }; + + /** 页面不需要显示的列表字段 */ + public static final String[] COLUMNNAME_NOT_LIST = { "id", "create_by", "create_time", "del_flag", "update_by", + "update_time" }; + + /** 页面不需要查询字段 */ + public static final String[] COLUMNNAME_NOT_QUERY = { "id", "create_by", "create_time", "del_flag", "update_by", + "update_time", "remark" }; + + /** Entity基类字段 */ + public static final String[] BASE_ENTITY = { "createBy", "createTime", "updateBy", "updateTime", "remark" }; + + /** Tree基类字段 */ + public static final String[] TREE_ENTITY = { "parentName", "parentId", "orderNum", "ancestors", "children" }; + + /** 文本框 */ + public static final String HTML_INPUT = "input"; + + /** 文本域 */ + public static final String HTML_TEXTAREA = "textarea"; + + /** 下拉框 */ + public static final String HTML_SELECT = "select"; + + /** 单选框 */ + public static final String HTML_RADIO = "radio"; + + /** 复选框 */ + public static final String HTML_CHECKBOX = "checkbox"; + + /** 日期控件 */ + public static final String HTML_DATETIME = "datetime"; + + /** 图片上传控件 */ + public static final String HTML_IMAGE_UPLOAD = "imageUpload"; + + /** 文件上传控件 */ + public static final String HTML_FILE_UPLOAD = "fileUpload"; + + /** 富文本控件 */ + public static final String HTML_EDITOR = "editor"; + + /** 字符串类型 */ + public static final String TYPE_STRING = "String"; + + /** 整型 */ + public static final String TYPE_INTEGER = "Integer"; + + /** 长整型 */ + public static final String TYPE_LONG = "Long"; + + /** 浮点型 */ + public static final String TYPE_DOUBLE = "Double"; + + /** 高精度计算类型 */ + public static final String TYPE_BIGDECIMAL = "BigDecimal"; + + /** 时间类型 */ + public static final String TYPE_DATE = "Date"; + + /** LocalDateTime时间类型 */ + public static final String TYPE_LOCAL_DATE_TIME = "LocalDateTime"; + + /** 模糊查询 */ + public static final String QUERY_LIKE = "LIKE"; + + /** 相等查询 */ + public static final String QUERY_EQ = "EQ"; + + /** 需要 */ + public static final String REQUIRE = "1"; + + /** MySql tinyint 类型 */ + public static final String MYSQL_TINYINT = "tinyint"; + + /** MySql int 类型 */ + public static final String MYSQL_INT = "int"; +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/constant/HttpStatus.java b/zzyl-common/src/main/java/com/zzyl/common/constant/HttpStatus.java new file mode 100644 index 0000000..f082f8f --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/constant/HttpStatus.java @@ -0,0 +1,94 @@ +package com.zzyl.common.constant; + +/** + * 返回状态码 + * + * @author ruoyi + */ +public class HttpStatus +{ + /** + * 操作成功 + */ + public static final int SUCCESS = 200; + + /** + * 对象创建成功 + */ + public static final int CREATED = 201; + + /** + * 请求已经被接受 + */ + public static final int ACCEPTED = 202; + + /** + * 操作已经执行成功,但是没有返回数据 + */ + public static final int NO_CONTENT = 204; + + /** + * 资源已被移除 + */ + public static final int MOVED_PERM = 301; + + /** + * 重定向 + */ + public static final int SEE_OTHER = 303; + + /** + * 资源没有被修改 + */ + public static final int NOT_MODIFIED = 304; + + /** + * 参数列表错误(缺少,格式不匹配) + */ + public static final int BAD_REQUEST = 400; + + /** + * 未授权 + */ + public static final int UNAUTHORIZED = 401; + + /** + * 访问受限,授权过期 + */ + public static final int FORBIDDEN = 403; + + /** + * 资源,服务未找到 + */ + public static final int NOT_FOUND = 404; + + /** + * 不允许的http方法 + */ + public static final int BAD_METHOD = 405; + + /** + * 资源冲突,或者资源被锁 + */ + public static final int CONFLICT = 409; + + /** + * 不支持的数据,媒体类型 + */ + public static final int UNSUPPORTED_TYPE = 415; + + /** + * 系统内部错误 + */ + public static final int ERROR = 500; + + /** + * 接口未实现 + */ + public static final int NOT_IMPLEMENTED = 501; + + /** + * 系统警告消息 + */ + public static final int WARN = 601; +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/constant/ScheduleConstants.java b/zzyl-common/src/main/java/com/zzyl/common/constant/ScheduleConstants.java new file mode 100644 index 0000000..7526159 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/constant/ScheduleConstants.java @@ -0,0 +1,50 @@ +package com.zzyl.common.constant; + +/** + * 任务调度通用常量 + * + * @author ruoyi + */ +public class ScheduleConstants +{ + public static final String TASK_CLASS_NAME = "TASK_CLASS_NAME"; + + /** 执行目标key */ + public static final String TASK_PROPERTIES = "TASK_PROPERTIES"; + + /** 默认 */ + public static final String MISFIRE_DEFAULT = "0"; + + /** 立即触发执行 */ + public static final String MISFIRE_IGNORE_MISFIRES = "1"; + + /** 触发一次执行 */ + public static final String MISFIRE_FIRE_AND_PROCEED = "2"; + + /** 不触发立即执行 */ + public static final String MISFIRE_DO_NOTHING = "3"; + + public enum Status + { + /** + * 正常 + */ + NORMAL("0"), + /** + * 暂停 + */ + PAUSE("1"); + + private String value; + + private Status(String value) + { + this.value = value; + } + + public String getValue() + { + return value; + } + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/constant/UserConstants.java b/zzyl-common/src/main/java/com/zzyl/common/constant/UserConstants.java new file mode 100644 index 0000000..cc21aa3 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/constant/UserConstants.java @@ -0,0 +1,81 @@ +package com.zzyl.common.constant; + +/** + * 用户常量信息 + * + * @author ruoyi + */ +public class UserConstants +{ + /** + * 平台内系统用户的唯一标志 + */ + public static final String SYS_USER = "SYS_USER"; + + /** 正常状态 */ + public static final String NORMAL = "0"; + + /** 异常状态 */ + public static final String EXCEPTION = "1"; + + /** 用户封禁状态 */ + public static final String USER_DISABLE = "1"; + + /** 角色正常状态 */ + public static final String ROLE_NORMAL = "0"; + + /** 角色封禁状态 */ + public static final String ROLE_DISABLE = "1"; + + /** 部门正常状态 */ + public static final String DEPT_NORMAL = "0"; + + /** 部门停用状态 */ + public static final String DEPT_DISABLE = "1"; + + /** 字典正常状态 */ + public static final String DICT_NORMAL = "0"; + + /** 是否为系统默认(是) */ + public static final String YES = "Y"; + + /** 是否菜单外链(是) */ + public static final String YES_FRAME = "0"; + + /** 是否菜单外链(否) */ + public static final String NO_FRAME = "1"; + + /** 菜单类型(目录) */ + public static final String TYPE_DIR = "M"; + + /** 菜单类型(菜单) */ + public static final String TYPE_MENU = "C"; + + /** 菜单类型(按钮) */ + public static final String TYPE_BUTTON = "F"; + + /** Layout组件标识 */ + public final static String LAYOUT = "Layout"; + + /** ParentView组件标识 */ + public final static String PARENT_VIEW = "ParentView"; + + /** InnerLink组件标识 */ + public final static String INNER_LINK = "InnerLink"; + + /** 校验是否唯一的返回标识 */ + public final static boolean UNIQUE = true; + public final static boolean NOT_UNIQUE = false; + + /** + * 用户名长度限制 + */ + public static final int USERNAME_MIN_LENGTH = 2; + public static final int USERNAME_MAX_LENGTH = 20; + + /** + * 密码长度限制 + */ + public static final int PASSWORD_MIN_LENGTH = 5; + public static final int PASSWORD_MAX_LENGTH = 20; +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/core/controller/BaseController.java b/zzyl-common/src/main/java/com/zzyl/common/core/controller/BaseController.java new file mode 100644 index 0000000..9eb56eb --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/core/controller/BaseController.java @@ -0,0 +1,202 @@ +package com.zzyl.common.core.controller; + +import java.beans.PropertyEditorSupport; +import java.util.Date; +import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.bind.WebDataBinder; +import org.springframework.web.bind.annotation.InitBinder; +import com.github.pagehelper.PageHelper; +import com.github.pagehelper.PageInfo; +import com.zzyl.common.constant.HttpStatus; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.core.domain.model.LoginUser; +import com.zzyl.common.core.page.PageDomain; +import com.zzyl.common.core.page.TableDataInfo; +import com.zzyl.common.core.page.TableSupport; +import com.zzyl.common.utils.DateUtils; +import com.zzyl.common.utils.PageUtils; +import com.zzyl.common.utils.SecurityUtils; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.common.utils.sql.SqlUtil; + +/** + * web层通用数据处理 + * + * @author ruoyi + */ +public class BaseController +{ + protected final Logger logger = LoggerFactory.getLogger(this.getClass()); + + /** + * 将前台传递过来的日期格式的字符串,自动转化为Date类型 + */ + @InitBinder + public void initBinder(WebDataBinder binder) + { + // Date 类型转换 + binder.registerCustomEditor(Date.class, new PropertyEditorSupport() + { + @Override + public void setAsText(String text) + { + setValue(DateUtils.parseDate(text)); + } + }); + } + + /** + * 设置请求分页数据 + */ + protected void startPage() + { + PageUtils.startPage(); + } + + /** + * 设置请求排序数据 + */ + protected void startOrderBy() + { + PageDomain pageDomain = TableSupport.buildPageRequest(); + if (StringUtils.isNotEmpty(pageDomain.getOrderBy())) + { + String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy()); + PageHelper.orderBy(orderBy); + } + } + + /** + * 清理分页的线程变量 + */ + protected void clearPage() + { + PageUtils.clearPage(); + } + + /** + * 响应请求分页数据 + */ + @SuppressWarnings({ "rawtypes", "unchecked" }) + protected TableDataInfo getDataTable(List list) + { + TableDataInfo rspData = new TableDataInfo(); + rspData.setCode(HttpStatus.SUCCESS); + rspData.setMsg("查询成功"); + rspData.setRows(list); + rspData.setTotal(new PageInfo(list).getTotal()); + return rspData; + } + + /** + * 返回成功 + */ + public AjaxResult success() + { + return AjaxResult.success(); + } + + /** + * 返回失败消息 + */ + public AjaxResult error() + { + return AjaxResult.error(); + } + + /** + * 返回成功消息 + */ + public AjaxResult success(String message) + { + return AjaxResult.success(message); + } + + /** + * 返回成功消息 + */ + public AjaxResult success(Object data) + { + return AjaxResult.success(data); + } + + /** + * 返回失败消息 + */ + public AjaxResult error(String message) + { + return AjaxResult.error(message); + } + + /** + * 返回警告消息 + */ + public AjaxResult warn(String message) + { + return AjaxResult.warn(message); + } + + /** + * 响应返回结果 + * + * @param rows 影响行数 + * @return 操作结果 + */ + protected AjaxResult toAjax(int rows) + { + return rows > 0 ? AjaxResult.success() : AjaxResult.error(); + } + + /** + * 响应返回结果 + * + * @param result 结果 + * @return 操作结果 + */ + protected AjaxResult toAjax(boolean result) + { + return result ? success() : error(); + } + + /** + * 页面跳转 + */ + public String redirect(String url) + { + return StringUtils.format("redirect:{}", url); + } + + /** + * 获取用户缓存信息 + */ + public LoginUser getLoginUser() + { + return SecurityUtils.getLoginUser(); + } + + /** + * 获取登录用户id + */ + public Long getUserId() + { + return getLoginUser().getUserId(); + } + + /** + * 获取登录部门id + */ + public Long getDeptId() + { + return getLoginUser().getDeptId(); + } + + /** + * 获取登录用户名 + */ + public String getUsername() + { + return getLoginUser().getUsername(); + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/core/domain/AjaxResult.java b/zzyl-common/src/main/java/com/zzyl/common/core/domain/AjaxResult.java new file mode 100644 index 0000000..f7fc8e8 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/core/domain/AjaxResult.java @@ -0,0 +1,202 @@ +package com.zzyl.common.core.domain; + +import java.util.HashMap; +import java.util.Objects; +import com.zzyl.common.constant.HttpStatus; +import com.zzyl.common.utils.StringUtils; + +/** + * 操作消息提醒 + * + * @author ruoyi + */ +public class AjaxResult extends HashMap +{ + private static final long serialVersionUID = 1L; + + /** 状态码 */ + public static final String CODE_TAG = "code"; + + /** 返回内容 */ + public static final String MSG_TAG = "msg"; + + /** 数据对象 */ + public static final String DATA_TAG = "data"; + + /** + * 初始化一个新创建的 AjaxResult 对象,使其表示一个空消息。 + */ + public AjaxResult() + { + } + + /** + * 初始化一个新创建的 AjaxResult 对象 + * @param code 状态码 + * @param msg 返回内容 + */ + public AjaxResult(int code, String msg) + { + super.put(CODE_TAG, code); + super.put(MSG_TAG, msg); + } + + /** + * 初始化一个新创建的 AjaxResult 对象 + * @param code 状态码 + * @param msg 返回内容 + * @param data 数据对象 + */ + public AjaxResult(int code, String msg, Object data) + { + super.put(CODE_TAG, code); + super.put(MSG_TAG, msg); + if (StringUtils.isNotNull(data)) + { + super.put(DATA_TAG, data); + } + } + + /** + * 返回成功消息 + * @return 成功消息 + */ + public static AjaxResult success() + { + return AjaxResult.success("操作成功"); + } + + /** + * 返回成功数据 + * @return 成功消息 + */ + public static AjaxResult success(Object data) + { + return AjaxResult.success("操作成功", data); + } + + /** + * 返回成功消息 + * + * @param msg 返回内容 + * @return 成功消息 + */ + public static AjaxResult success(String msg) + { + return AjaxResult.success(msg, null); + } + + /** + * 返回成功消息 + * + * @param msg 返回内容 + * @param data 数据对象 + * @return 成功消息 + */ + public static AjaxResult success(String msg, Object data) + { + return new AjaxResult(HttpStatus.SUCCESS, msg, data); + } + + /** + * 返回警告消息 + * @param msg 返回内容 + * @return 警告消息 + */ + public static AjaxResult warn(String msg) + { + return AjaxResult.warn(msg, null); + } + + /** + * 返回警告消息 + * @param msg 返回内容 + * @param data 数据对象 + * @return 警告消息 + */ + public static AjaxResult warn(String msg, Object data) + { + return new AjaxResult(HttpStatus.WARN, msg, data); + } + + /** + * 返回错误消息 + * @return 错误消息 + */ + public static AjaxResult error() + { + return AjaxResult.error("操作失败"); + } + + /** + * 返回错误消息 + * @param msg 返回内容 + * @return 错误消息 + */ + public static AjaxResult error(String msg) + { + return AjaxResult.error(msg, null); + } + + /** + * 返回错误消息 + * @param msg 返回内容 + * @param data 数据对象 + * @return 错误消息 + */ + public static AjaxResult error(String msg, Object data) + { + return new AjaxResult(HttpStatus.ERROR, msg, data); + } + + /** + * 返回错误消息 + * @param code 状态码 + * @param msg 返回内容 + * @return 错误消息 + */ + public static AjaxResult error(int code, String msg) + { + return new AjaxResult(code, msg, null); + } + + /** + * 是否为成功消息 + * @return 结果 + */ + public boolean isSuccess() + { + return Objects.equals(HttpStatus.SUCCESS, this.get(CODE_TAG)); + } + + /** + * 是否为警告消息 + * @return 结果 + */ + public boolean isWarn() + { + return Objects.equals(HttpStatus.WARN, this.get(CODE_TAG)); + } + + /** + * 是否为错误消息 + * @return 结果 + */ + public boolean isError() + { + return Objects.equals(HttpStatus.ERROR, this.get(CODE_TAG)); + } + + /** + * 方便链式调用 + * @param key 键 + * @param value 值 + * @return 数据对象 + */ + @Override + public AjaxResult put(String key, Object value) + { + super.put(key, value); + return this; + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/core/domain/BaseEntity.java b/zzyl-common/src/main/java/com/zzyl/common/core/domain/BaseEntity.java new file mode 100644 index 0000000..9022aa4 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/core/domain/BaseEntity.java @@ -0,0 +1,137 @@ +package com.zzyl.common.core.domain; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.io.Serializable; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +/** + * Entity基类 + * + * @author ruoyi + */ +@ApiModel(description = "实体基类") +public class BaseEntity implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** 搜索值 */ + @JsonIgnore + @ApiModelProperty(hidden = true) + @TableField(exist = false) + private String searchValue; + + /** 创建者 */ + @ApiModelProperty(value = "创建者") + @TableField(fill = FieldFill.INSERT) + private String createBy; + + /** 创建时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value = "创建时间") + @TableField(fill = FieldFill.INSERT) + private Date createTime; + + /** 更新者 */ + @ApiModelProperty(value = "更新者") + @TableField(fill = FieldFill.UPDATE) + private String updateBy; + + /** 更新时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value = "更新时间") + @TableField(fill = FieldFill.UPDATE) + private Date updateTime; + + /** 备注 */ + @ApiModelProperty(value = "备注") + private String remark; + + /** 请求参数 */ + @JsonInclude(JsonInclude.Include.NON_EMPTY) + @ApiModelProperty(value = "请求参数") + @TableField(exist = false) + private Map params; + + public String getSearchValue() + { + return searchValue; + } + + public void setSearchValue(String searchValue) + { + this.searchValue = searchValue; + } + + public String getCreateBy() + { + return createBy; + } + + public void setCreateBy(String createBy) + { + this.createBy = createBy; + } + + public Date getCreateTime() + { + return createTime; + } + + public void setCreateTime(Date createTime) + { + this.createTime = createTime; + } + + public String getUpdateBy() + { + return updateBy; + } + + public void setUpdateBy(String updateBy) + { + this.updateBy = updateBy; + } + + public Date getUpdateTime() + { + return updateTime; + } + + public void setUpdateTime(Date updateTime) + { + this.updateTime = updateTime; + } + + public String getRemark() + { + return remark; + } + + public void setRemark(String remark) + { + this.remark = remark; + } + + public Map getParams() + { + if (params == null) + { + params = new HashMap<>(); + } + return params; + } + + public void setParams(Map params) + { + this.params = params; + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/core/domain/R.java b/zzyl-common/src/main/java/com/zzyl/common/core/domain/R.java new file mode 100644 index 0000000..736a8bb --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/core/domain/R.java @@ -0,0 +1,115 @@ +package com.zzyl.common.core.domain; + +import java.io.Serializable; +import com.zzyl.common.constant.HttpStatus; + +/** + * 响应信息主体 + * + * @author ruoyi + */ +public class R implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** 成功 */ + public static final int SUCCESS = HttpStatus.SUCCESS; + + /** 失败 */ + public static final int FAIL = HttpStatus.ERROR; + + private int code; + + private String msg; + + private T data; + + public static R ok() + { + return restResult(null, SUCCESS, "操作成功"); + } + + public static R ok(T data) + { + return restResult(data, SUCCESS, "操作成功"); + } + + public static R ok(T data, String msg) + { + return restResult(data, SUCCESS, msg); + } + + public static R fail() + { + return restResult(null, FAIL, "操作失败"); + } + + public static R fail(String msg) + { + return restResult(null, FAIL, msg); + } + + public static R fail(T data) + { + return restResult(data, FAIL, "操作失败"); + } + + public static R fail(T data, String msg) + { + return restResult(data, FAIL, msg); + } + + public static R fail(int code, String msg) + { + return restResult(null, code, msg); + } + + private static R restResult(T data, int code, String msg) + { + R apiResult = new R<>(); + apiResult.setCode(code); + apiResult.setData(data); + apiResult.setMsg(msg); + return apiResult; + } + + public int getCode() + { + return code; + } + + public void setCode(int code) + { + this.code = code; + } + + public String getMsg() + { + return msg; + } + + public void setMsg(String msg) + { + this.msg = msg; + } + + public T getData() + { + return data; + } + + public void setData(T data) + { + this.data = data; + } + + public static Boolean isError(R ret) + { + return !isSuccess(ret); + } + + public static Boolean isSuccess(R ret) + { + return R.SUCCESS == ret.getCode(); + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/core/domain/TreeEntity.java b/zzyl-common/src/main/java/com/zzyl/common/core/domain/TreeEntity.java new file mode 100644 index 0000000..aed2a75 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/core/domain/TreeEntity.java @@ -0,0 +1,79 @@ +package com.zzyl.common.core.domain; + +import java.util.ArrayList; +import java.util.List; + +/** + * Tree基类 + * + * @author ruoyi + */ +public class TreeEntity extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 父菜单名称 */ + private String parentName; + + /** 父菜单ID */ + private Long parentId; + + /** 显示顺序 */ + private Integer orderNum; + + /** 祖级列表 */ + private String ancestors; + + /** 子部门 */ + private List children = new ArrayList<>(); + + public String getParentName() + { + return parentName; + } + + public void setParentName(String parentName) + { + this.parentName = parentName; + } + + public Long getParentId() + { + return parentId; + } + + public void setParentId(Long parentId) + { + this.parentId = parentId; + } + + public Integer getOrderNum() + { + return orderNum; + } + + public void setOrderNum(Integer orderNum) + { + this.orderNum = orderNum; + } + + public String getAncestors() + { + return ancestors; + } + + public void setAncestors(String ancestors) + { + this.ancestors = ancestors; + } + + public List getChildren() + { + return children; + } + + public void setChildren(List children) + { + this.children = children; + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/core/domain/TreeSelect.java b/zzyl-common/src/main/java/com/zzyl/common/core/domain/TreeSelect.java new file mode 100644 index 0000000..6b747e6 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/core/domain/TreeSelect.java @@ -0,0 +1,93 @@ +package com.zzyl.common.core.domain; + +import java.io.Serializable; +import java.util.List; +import java.util.stream.Collectors; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.zzyl.common.constant.UserConstants; +import com.zzyl.common.core.domain.entity.SysDept; +import com.zzyl.common.core.domain.entity.SysMenu; +import com.zzyl.common.utils.StringUtils; + +/** + * Treeselect树结构实体类 + * + * @author ruoyi + */ +public class TreeSelect implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** 节点ID */ + private Long id; + + /** 节点名称 */ + private String label; + + /** 节点禁用 */ + private boolean disabled = false; + + /** 子节点 */ + @JsonInclude(JsonInclude.Include.NON_EMPTY) + private List children; + + public TreeSelect() + { + + } + + public TreeSelect(SysDept dept) + { + this.id = dept.getDeptId(); + this.label = dept.getDeptName(); + this.disabled = StringUtils.equals(UserConstants.DEPT_DISABLE, dept.getStatus()); + this.children = dept.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList()); + } + + public TreeSelect(SysMenu menu) + { + this.id = menu.getMenuId(); + this.label = menu.getMenuName(); + this.children = menu.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList()); + } + + public Long getId() + { + return id; + } + + public void setId(Long id) + { + this.id = id; + } + + public String getLabel() + { + return label; + } + + public void setLabel(String label) + { + this.label = label; + } + + public boolean isDisabled() + { + return disabled; + } + + public void setDisabled(boolean disabled) + { + this.disabled = disabled; + } + + public List getChildren() + { + return children; + } + + public void setChildren(List children) + { + this.children = children; + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/core/domain/entity/SysDept.java b/zzyl-common/src/main/java/com/zzyl/common/core/domain/entity/SysDept.java new file mode 100644 index 0000000..e3231cc --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/core/domain/entity/SysDept.java @@ -0,0 +1,203 @@ +package com.zzyl.common.core.domain.entity; + +import java.util.ArrayList; +import java.util.List; +import javax.validation.constraints.Email; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.zzyl.common.core.domain.BaseEntity; + +/** + * 部门表 sys_dept + * + * @author ruoyi + */ +public class SysDept extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 部门ID */ + private Long deptId; + + /** 父部门ID */ + private Long parentId; + + /** 祖级列表 */ + private String ancestors; + + /** 部门名称 */ + private String deptName; + + /** 显示顺序 */ + private Integer orderNum; + + /** 负责人 */ + private String leader; + + /** 联系电话 */ + private String phone; + + /** 邮箱 */ + private String email; + + /** 部门状态:0正常,1停用 */ + private String status; + + /** 删除标志(0代表存在 2代表删除) */ + private String delFlag; + + /** 父部门名称 */ + private String parentName; + + /** 子部门 */ + private List children = new ArrayList(); + + public Long getDeptId() + { + return deptId; + } + + public void setDeptId(Long deptId) + { + this.deptId = deptId; + } + + public Long getParentId() + { + return parentId; + } + + public void setParentId(Long parentId) + { + this.parentId = parentId; + } + + public String getAncestors() + { + return ancestors; + } + + public void setAncestors(String ancestors) + { + this.ancestors = ancestors; + } + + @NotBlank(message = "部门名称不能为空") + @Size(min = 0, max = 30, message = "部门名称长度不能超过30个字符") + public String getDeptName() + { + return deptName; + } + + public void setDeptName(String deptName) + { + this.deptName = deptName; + } + + @NotNull(message = "显示顺序不能为空") + public Integer getOrderNum() + { + return orderNum; + } + + public void setOrderNum(Integer orderNum) + { + this.orderNum = orderNum; + } + + public String getLeader() + { + return leader; + } + + public void setLeader(String leader) + { + this.leader = leader; + } + + @Size(min = 0, max = 11, message = "联系电话长度不能超过11个字符") + public String getPhone() + { + return phone; + } + + public void setPhone(String phone) + { + this.phone = phone; + } + + @Email(message = "邮箱格式不正确") + @Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符") + public String getEmail() + { + return email; + } + + public void setEmail(String email) + { + this.email = email; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + public String getDelFlag() + { + return delFlag; + } + + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public String getParentName() + { + return parentName; + } + + public void setParentName(String parentName) + { + this.parentName = parentName; + } + + public List getChildren() + { + return children; + } + + public void setChildren(List children) + { + this.children = children; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("deptId", getDeptId()) + .append("parentId", getParentId()) + .append("ancestors", getAncestors()) + .append("deptName", getDeptName()) + .append("orderNum", getOrderNum()) + .append("leader", getLeader()) + .append("phone", getPhone()) + .append("email", getEmail()) + .append("status", getStatus()) + .append("delFlag", getDelFlag()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/core/domain/entity/SysDictData.java b/zzyl-common/src/main/java/com/zzyl/common/core/domain/entity/SysDictData.java new file mode 100644 index 0000000..f1daa6d --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/core/domain/entity/SysDictData.java @@ -0,0 +1,176 @@ +package com.zzyl.common.core.domain.entity; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.zzyl.common.annotation.Excel; +import com.zzyl.common.annotation.Excel.ColumnType; +import com.zzyl.common.constant.UserConstants; +import com.zzyl.common.core.domain.BaseEntity; + +/** + * 字典数据表 sys_dict_data + * + * @author ruoyi + */ +public class SysDictData extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 字典编码 */ + @Excel(name = "字典编码", cellType = ColumnType.NUMERIC) + private Long dictCode; + + /** 字典排序 */ + @Excel(name = "字典排序", cellType = ColumnType.NUMERIC) + private Long dictSort; + + /** 字典标签 */ + @Excel(name = "字典标签") + private String dictLabel; + + /** 字典键值 */ + @Excel(name = "字典键值") + private String dictValue; + + /** 字典类型 */ + @Excel(name = "字典类型") + private String dictType; + + /** 样式属性(其他样式扩展) */ + private String cssClass; + + /** 表格字典样式 */ + private String listClass; + + /** 是否默认(Y是 N否) */ + @Excel(name = "是否默认", readConverterExp = "Y=是,N=否") + private String isDefault; + + /** 状态(0正常 1停用) */ + @Excel(name = "状态", readConverterExp = "0=正常,1=停用") + private String status; + + public Long getDictCode() + { + return dictCode; + } + + public void setDictCode(Long dictCode) + { + this.dictCode = dictCode; + } + + public Long getDictSort() + { + return dictSort; + } + + public void setDictSort(Long dictSort) + { + this.dictSort = dictSort; + } + + @NotBlank(message = "字典标签不能为空") + @Size(min = 0, max = 100, message = "字典标签长度不能超过100个字符") + public String getDictLabel() + { + return dictLabel; + } + + public void setDictLabel(String dictLabel) + { + this.dictLabel = dictLabel; + } + + @NotBlank(message = "字典键值不能为空") + @Size(min = 0, max = 100, message = "字典键值长度不能超过100个字符") + public String getDictValue() + { + return dictValue; + } + + public void setDictValue(String dictValue) + { + this.dictValue = dictValue; + } + + @NotBlank(message = "字典类型不能为空") + @Size(min = 0, max = 100, message = "字典类型长度不能超过100个字符") + public String getDictType() + { + return dictType; + } + + public void setDictType(String dictType) + { + this.dictType = dictType; + } + + @Size(min = 0, max = 100, message = "样式属性长度不能超过100个字符") + public String getCssClass() + { + return cssClass; + } + + public void setCssClass(String cssClass) + { + this.cssClass = cssClass; + } + + public String getListClass() + { + return listClass; + } + + public void setListClass(String listClass) + { + this.listClass = listClass; + } + + public boolean getDefault() + { + return UserConstants.YES.equals(this.isDefault); + } + + public String getIsDefault() + { + return isDefault; + } + + public void setIsDefault(String isDefault) + { + this.isDefault = isDefault; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("dictCode", getDictCode()) + .append("dictSort", getDictSort()) + .append("dictLabel", getDictLabel()) + .append("dictValue", getDictValue()) + .append("dictType", getDictType()) + .append("cssClass", getCssClass()) + .append("listClass", getListClass()) + .append("isDefault", getIsDefault()) + .append("status", getStatus()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/core/domain/entity/SysDictType.java b/zzyl-common/src/main/java/com/zzyl/common/core/domain/entity/SysDictType.java new file mode 100644 index 0000000..0bf2048 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/core/domain/entity/SysDictType.java @@ -0,0 +1,96 @@ +package com.zzyl.common.core.domain.entity; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Pattern; +import javax.validation.constraints.Size; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.zzyl.common.annotation.Excel; +import com.zzyl.common.annotation.Excel.ColumnType; +import com.zzyl.common.core.domain.BaseEntity; + +/** + * 字典类型表 sys_dict_type + * + * @author ruoyi + */ +public class SysDictType extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 字典主键 */ + @Excel(name = "字典主键", cellType = ColumnType.NUMERIC) + private Long dictId; + + /** 字典名称 */ + @Excel(name = "字典名称") + private String dictName; + + /** 字典类型 */ + @Excel(name = "字典类型") + private String dictType; + + /** 状态(0正常 1停用) */ + @Excel(name = "状态", readConverterExp = "0=正常,1=停用") + private String status; + + public Long getDictId() + { + return dictId; + } + + public void setDictId(Long dictId) + { + this.dictId = dictId; + } + + @NotBlank(message = "字典名称不能为空") + @Size(min = 0, max = 100, message = "字典类型名称长度不能超过100个字符") + public String getDictName() + { + return dictName; + } + + public void setDictName(String dictName) + { + this.dictName = dictName; + } + + @NotBlank(message = "字典类型不能为空") + @Size(min = 0, max = 100, message = "字典类型类型长度不能超过100个字符") + @Pattern(regexp = "^[a-z][a-z0-9_]*$", message = "字典类型必须以字母开头,且只能为(小写字母,数字,下滑线)") + public String getDictType() + { + return dictType; + } + + public void setDictType(String dictType) + { + this.dictType = dictType; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("dictId", getDictId()) + .append("dictName", getDictName()) + .append("dictType", getDictType()) + .append("status", getStatus()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/core/domain/entity/SysMenu.java b/zzyl-common/src/main/java/com/zzyl/common/core/domain/entity/SysMenu.java new file mode 100644 index 0000000..f5cc736 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/core/domain/entity/SysMenu.java @@ -0,0 +1,274 @@ +package com.zzyl.common.core.domain.entity; + +import java.util.ArrayList; +import java.util.List; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.zzyl.common.core.domain.BaseEntity; + +/** + * 菜单权限表 sys_menu + * + * @author ruoyi + */ +public class SysMenu extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 菜单ID */ + private Long menuId; + + /** 菜单名称 */ + private String menuName; + + /** 父菜单名称 */ + private String parentName; + + /** 父菜单ID */ + private Long parentId; + + /** 显示顺序 */ + private Integer orderNum; + + /** 路由地址 */ + private String path; + + /** 组件路径 */ + private String component; + + /** 路由参数 */ + private String query; + + /** 路由名称,默认和路由地址相同的驼峰格式(注意:因为vue3版本的router会删除名称相同路由,为避免名字的冲突,特殊情况可以自定义) */ + private String routeName; + + /** 是否为外链(0是 1否) */ + private String isFrame; + + /** 是否缓存(0缓存 1不缓存) */ + private String isCache; + + /** 类型(M目录 C菜单 F按钮) */ + private String menuType; + + /** 显示状态(0显示 1隐藏) */ + private String visible; + + /** 菜单状态(0正常 1停用) */ + private String status; + + /** 权限字符串 */ + private String perms; + + /** 菜单图标 */ + private String icon; + + /** 子菜单 */ + private List children = new ArrayList(); + + public Long getMenuId() + { + return menuId; + } + + public void setMenuId(Long menuId) + { + this.menuId = menuId; + } + + @NotBlank(message = "菜单名称不能为空") + @Size(min = 0, max = 50, message = "菜单名称长度不能超过50个字符") + public String getMenuName() + { + return menuName; + } + + public void setMenuName(String menuName) + { + this.menuName = menuName; + } + + public String getParentName() + { + return parentName; + } + + public void setParentName(String parentName) + { + this.parentName = parentName; + } + + public Long getParentId() + { + return parentId; + } + + public void setParentId(Long parentId) + { + this.parentId = parentId; + } + + @NotNull(message = "显示顺序不能为空") + public Integer getOrderNum() + { + return orderNum; + } + + public void setOrderNum(Integer orderNum) + { + this.orderNum = orderNum; + } + + @Size(min = 0, max = 200, message = "路由地址不能超过200个字符") + public String getPath() + { + return path; + } + + public void setPath(String path) + { + this.path = path; + } + + @Size(min = 0, max = 200, message = "组件路径不能超过255个字符") + public String getComponent() + { + return component; + } + + public void setComponent(String component) + { + this.component = component; + } + + public String getQuery() + { + return query; + } + + public void setQuery(String query) + { + this.query = query; + } + + public String getRouteName() + { + return routeName; + } + + public void setRouteName(String routeName) + { + this.routeName = routeName; + } + + public String getIsFrame() + { + return isFrame; + } + + public void setIsFrame(String isFrame) + { + this.isFrame = isFrame; + } + + public String getIsCache() + { + return isCache; + } + + public void setIsCache(String isCache) + { + this.isCache = isCache; + } + + @NotBlank(message = "菜单类型不能为空") + public String getMenuType() + { + return menuType; + } + + public void setMenuType(String menuType) + { + this.menuType = menuType; + } + + public String getVisible() + { + return visible; + } + + public void setVisible(String visible) + { + this.visible = visible; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + @Size(min = 0, max = 100, message = "权限标识长度不能超过100个字符") + public String getPerms() + { + return perms; + } + + public void setPerms(String perms) + { + this.perms = perms; + } + + public String getIcon() + { + return icon; + } + + public void setIcon(String icon) + { + this.icon = icon; + } + + public List getChildren() + { + return children; + } + + public void setChildren(List children) + { + this.children = children; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("menuId", getMenuId()) + .append("menuName", getMenuName()) + .append("parentId", getParentId()) + .append("orderNum", getOrderNum()) + .append("path", getPath()) + .append("component", getComponent()) + .append("query", getQuery()) + .append("routeName", getRouteName()) + .append("isFrame", getIsFrame()) + .append("IsCache", getIsCache()) + .append("menuType", getMenuType()) + .append("visible", getVisible()) + .append("status ", getStatus()) + .append("perms", getPerms()) + .append("icon", getIcon()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/core/domain/entity/SysRole.java b/zzyl-common/src/main/java/com/zzyl/common/core/domain/entity/SysRole.java new file mode 100644 index 0000000..ab992f4 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/core/domain/entity/SysRole.java @@ -0,0 +1,241 @@ +package com.zzyl.common.core.domain.entity; + +import java.util.Set; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.zzyl.common.annotation.Excel; +import com.zzyl.common.annotation.Excel.ColumnType; +import com.zzyl.common.core.domain.BaseEntity; + +/** + * 角色表 sys_role + * + * @author ruoyi + */ +public class SysRole extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 角色ID */ + @Excel(name = "角色序号", cellType = ColumnType.NUMERIC) + private Long roleId; + + /** 角色名称 */ + @Excel(name = "角色名称") + private String roleName; + + /** 角色权限 */ + @Excel(name = "角色权限") + private String roleKey; + + /** 角色排序 */ + @Excel(name = "角色排序") + private Integer roleSort; + + /** 数据范围(1:所有数据权限;2:自定义数据权限;3:本部门数据权限;4:本部门及以下数据权限;5:仅本人数据权限) */ + @Excel(name = "数据范围", readConverterExp = "1=所有数据权限,2=自定义数据权限,3=本部门数据权限,4=本部门及以下数据权限,5=仅本人数据权限") + private String dataScope; + + /** 菜单树选择项是否关联显示( 0:父子不互相关联显示 1:父子互相关联显示) */ + private boolean menuCheckStrictly; + + /** 部门树选择项是否关联显示(0:父子不互相关联显示 1:父子互相关联显示 ) */ + private boolean deptCheckStrictly; + + /** 角色状态(0正常 1停用) */ + @Excel(name = "角色状态", readConverterExp = "0=正常,1=停用") + private String status; + + /** 删除标志(0代表存在 2代表删除) */ + private String delFlag; + + /** 用户是否存在此角色标识 默认不存在 */ + private boolean flag = false; + + /** 菜单组 */ + private Long[] menuIds; + + /** 部门组(数据权限) */ + private Long[] deptIds; + + /** 角色菜单权限 */ + private Set permissions; + + public SysRole() + { + + } + + public SysRole(Long roleId) + { + this.roleId = roleId; + } + + public Long getRoleId() + { + return roleId; + } + + public void setRoleId(Long roleId) + { + this.roleId = roleId; + } + + public boolean isAdmin() + { + return isAdmin(this.roleId); + } + + public static boolean isAdmin(Long roleId) + { + return roleId != null && 1L == roleId; + } + + @NotBlank(message = "角色名称不能为空") + @Size(min = 0, max = 30, message = "角色名称长度不能超过30个字符") + public String getRoleName() + { + return roleName; + } + + public void setRoleName(String roleName) + { + this.roleName = roleName; + } + + @NotBlank(message = "权限字符不能为空") + @Size(min = 0, max = 100, message = "权限字符长度不能超过100个字符") + public String getRoleKey() + { + return roleKey; + } + + public void setRoleKey(String roleKey) + { + this.roleKey = roleKey; + } + + @NotNull(message = "显示顺序不能为空") + public Integer getRoleSort() + { + return roleSort; + } + + public void setRoleSort(Integer roleSort) + { + this.roleSort = roleSort; + } + + public String getDataScope() + { + return dataScope; + } + + public void setDataScope(String dataScope) + { + this.dataScope = dataScope; + } + + public boolean isMenuCheckStrictly() + { + return menuCheckStrictly; + } + + public void setMenuCheckStrictly(boolean menuCheckStrictly) + { + this.menuCheckStrictly = menuCheckStrictly; + } + + public boolean isDeptCheckStrictly() + { + return deptCheckStrictly; + } + + public void setDeptCheckStrictly(boolean deptCheckStrictly) + { + this.deptCheckStrictly = deptCheckStrictly; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + public String getDelFlag() + { + return delFlag; + } + + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public boolean isFlag() + { + return flag; + } + + public void setFlag(boolean flag) + { + this.flag = flag; + } + + public Long[] getMenuIds() + { + return menuIds; + } + + public void setMenuIds(Long[] menuIds) + { + this.menuIds = menuIds; + } + + public Long[] getDeptIds() + { + return deptIds; + } + + public void setDeptIds(Long[] deptIds) + { + this.deptIds = deptIds; + } + + public Set getPermissions() + { + return permissions; + } + + public void setPermissions(Set permissions) + { + this.permissions = permissions; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("roleId", getRoleId()) + .append("roleName", getRoleName()) + .append("roleKey", getRoleKey()) + .append("roleSort", getRoleSort()) + .append("dataScope", getDataScope()) + .append("menuCheckStrictly", isMenuCheckStrictly()) + .append("deptCheckStrictly", isDeptCheckStrictly()) + .append("status", getStatus()) + .append("delFlag", getDelFlag()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/core/domain/entity/SysUser.java b/zzyl-common/src/main/java/com/zzyl/common/core/domain/entity/SysUser.java new file mode 100644 index 0000000..6e628fb --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/core/domain/entity/SysUser.java @@ -0,0 +1,324 @@ +package com.zzyl.common.core.domain.entity; + +import java.util.Date; +import java.util.List; +import javax.validation.constraints.*; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.zzyl.common.annotation.Excel; +import com.zzyl.common.annotation.Excel.ColumnType; +import com.zzyl.common.annotation.Excel.Type; +import com.zzyl.common.annotation.Excels; +import com.zzyl.common.core.domain.BaseEntity; +import com.zzyl.common.xss.Xss; + +/** + * 用户对象 sys_user + * + * @author ruoyi + */ +public class SysUser extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 用户ID */ + @Excel(name = "用户序号", type = Type.EXPORT, cellType = ColumnType.NUMERIC, prompt = "用户编号") + private Long userId; + + /** 部门ID */ + @Excel(name = "部门编号", type = Type.IMPORT) + private Long deptId; + + /** 用户账号 */ + @Excel(name = "登录名称") + private String userName; + + /** 用户昵称 */ + @Excel(name = "用户名称") + private String nickName; + + /** 用户邮箱 */ + @Excel(name = "用户邮箱") + private String email; + + /** 手机号码 */ + @Excel(name = "手机号码", cellType = ColumnType.TEXT) + private String phonenumber; + + /** 用户性别 */ + @Excel(name = "用户性别", readConverterExp = "0=男,1=女,2=未知") + private String sex; + + /** 用户头像 */ + private String avatar; + + /** 密码 */ + private String password; + + /** 帐号状态(0正常 1停用) */ + @Excel(name = "帐号状态", readConverterExp = "0=正常,1=停用") + private String status; + + /** 删除标志(0代表存在 2代表删除) */ + private String delFlag; + + /** 最后登录IP */ + @Excel(name = "最后登录IP", type = Type.EXPORT) + private String loginIp; + + /** 最后登录时间 */ + @Excel(name = "最后登录时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Type.EXPORT) + private Date loginDate; + + /** 部门对象 */ + @Excels({ + @Excel(name = "部门名称", targetAttr = "deptName", type = Type.EXPORT), + @Excel(name = "部门负责人", targetAttr = "leader", type = Type.EXPORT) + }) + private SysDept dept; + + /** 角色对象 */ + private List roles; + + /** 角色组 */ + private Long[] roleIds; + + /** 岗位组 */ + private Long[] postIds; + + /** 角色ID */ + private Long roleId; + + public SysUser() + { + + } + + public SysUser(Long userId) + { + this.userId = userId; + } + + public Long getUserId() + { + return userId; + } + + public void setUserId(Long userId) + { + this.userId = userId; + } + + public boolean isAdmin() + { + return isAdmin(this.userId); + } + + public static boolean isAdmin(Long userId) + { + return userId != null && 1L == userId; + } + + public Long getDeptId() + { + return deptId; + } + + public void setDeptId(Long deptId) + { + this.deptId = deptId; + } + + @Xss(message = "用户昵称不能包含脚本字符") + @Size(min = 0, max = 30, message = "用户昵称长度不能超过30个字符") + public String getNickName() + { + return nickName; + } + + public void setNickName(String nickName) + { + this.nickName = nickName; + } + + @Xss(message = "用户账号不能包含脚本字符") + @NotBlank(message = "用户账号不能为空") + @Size(min = 0, max = 30, message = "用户账号长度不能超过30个字符") + public String getUserName() + { + return userName; + } + + public void setUserName(String userName) + { + this.userName = userName; + } + + @Email(message = "邮箱格式不正确") + @Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符") + public String getEmail() + { + return email; + } + + public void setEmail(String email) + { + this.email = email; + } + + @Size(min = 0, max = 11, message = "手机号码长度不能超过11个字符") + public String getPhonenumber() + { + return phonenumber; + } + + public void setPhonenumber(String phonenumber) + { + this.phonenumber = phonenumber; + } + + public String getSex() + { + return sex; + } + + public void setSex(String sex) + { + this.sex = sex; + } + + public String getAvatar() + { + return avatar; + } + + public void setAvatar(String avatar) + { + this.avatar = avatar; + } + + public String getPassword() + { + return password; + } + + public void setPassword(String password) + { + this.password = password; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + public String getDelFlag() + { + return delFlag; + } + + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public String getLoginIp() + { + return loginIp; + } + + public void setLoginIp(String loginIp) + { + this.loginIp = loginIp; + } + + public Date getLoginDate() + { + return loginDate; + } + + public void setLoginDate(Date loginDate) + { + this.loginDate = loginDate; + } + + public SysDept getDept() + { + return dept; + } + + public void setDept(SysDept dept) + { + this.dept = dept; + } + + public List getRoles() + { + return roles; + } + + public void setRoles(List roles) + { + this.roles = roles; + } + + public Long[] getRoleIds() + { + return roleIds; + } + + public void setRoleIds(Long[] roleIds) + { + this.roleIds = roleIds; + } + + public Long[] getPostIds() + { + return postIds; + } + + public void setPostIds(Long[] postIds) + { + this.postIds = postIds; + } + + public Long getRoleId() + { + return roleId; + } + + public void setRoleId(Long roleId) + { + this.roleId = roleId; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("userId", getUserId()) + .append("deptId", getDeptId()) + .append("userName", getUserName()) + .append("nickName", getNickName()) + .append("email", getEmail()) + .append("phonenumber", getPhonenumber()) + .append("sex", getSex()) + .append("avatar", getAvatar()) + .append("password", getPassword()) + .append("status", getStatus()) + .append("delFlag", getDelFlag()) + .append("loginIp", getLoginIp()) + .append("loginDate", getLoginDate()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .append("dept", getDept()) + .toString(); + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/core/domain/model/LoginBody.java b/zzyl-common/src/main/java/com/zzyl/common/core/domain/model/LoginBody.java new file mode 100644 index 0000000..1ae4d79 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/core/domain/model/LoginBody.java @@ -0,0 +1,69 @@ +package com.zzyl.common.core.domain.model; + +/** + * 用户登录对象 + * + * @author ruoyi + */ +public class LoginBody +{ + /** + * 用户名 + */ + private String username; + + /** + * 用户密码 + */ + private String password; + + /** + * 验证码 + */ + private String code; + + /** + * 唯一标识 + */ + private String uuid; + + public String getUsername() + { + return username; + } + + public void setUsername(String username) + { + this.username = username; + } + + public String getPassword() + { + return password; + } + + public void setPassword(String password) + { + this.password = password; + } + + public String getCode() + { + return code; + } + + public void setCode(String code) + { + this.code = code; + } + + public String getUuid() + { + return uuid; + } + + public void setUuid(String uuid) + { + this.uuid = uuid; + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/core/domain/model/LoginUser.java b/zzyl-common/src/main/java/com/zzyl/common/core/domain/model/LoginUser.java new file mode 100644 index 0000000..866da20 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/core/domain/model/LoginUser.java @@ -0,0 +1,266 @@ +package com.zzyl.common.core.domain.model; + +import com.alibaba.fastjson2.annotation.JSONField; +import com.zzyl.common.core.domain.entity.SysUser; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; +import java.util.Collection; +import java.util.Set; + +/** + * 登录用户身份权限 + * + * @author ruoyi + */ +public class LoginUser implements UserDetails +{ + private static final long serialVersionUID = 1L; + + /** + * 用户ID + */ + private Long userId; + + /** + * 部门ID + */ + private Long deptId; + + /** + * 用户唯一标识 + */ + private String token; + + /** + * 登录时间 + */ + private Long loginTime; + + /** + * 过期时间 + */ + private Long expireTime; + + /** + * 登录IP地址 + */ + private String ipaddr; + + /** + * 登录地点 + */ + private String loginLocation; + + /** + * 浏览器类型 + */ + private String browser; + + /** + * 操作系统 + */ + private String os; + + /** + * 权限列表 + */ + private Set permissions; + + /** + * 用户信息 + */ + private SysUser user; + + public LoginUser() + { + } + + public LoginUser(SysUser user, Set permissions) + { + this.user = user; + this.permissions = permissions; + } + + public LoginUser(Long userId, Long deptId, SysUser user, Set permissions) + { + this.userId = userId; + this.deptId = deptId; + this.user = user; + this.permissions = permissions; + } + + public Long getUserId() + { + return userId; + } + + public void setUserId(Long userId) + { + this.userId = userId; + } + + public Long getDeptId() + { + return deptId; + } + + public void setDeptId(Long deptId) + { + this.deptId = deptId; + } + + public String getToken() + { + return token; + } + + public void setToken(String token) + { + this.token = token; + } + + @JSONField(serialize = false) + @Override + public String getPassword() + { + return user.getPassword(); + } + + @Override + public String getUsername() + { + return user.getUserName(); + } + + /** + * 账户是否未过期,过期无法验证 + */ + @JSONField(serialize = false) + @Override + public boolean isAccountNonExpired() + { + return true; + } + + /** + * 指定用户是否解锁,锁定的用户无法进行身份验证 + * + * @return + */ + @JSONField(serialize = false) + @Override + public boolean isAccountNonLocked() + { + return true; + } + + /** + * 指示是否已过期的用户的凭据(密码),过期的凭据防止认证 + * + * @return + */ + @JSONField(serialize = false) + @Override + public boolean isCredentialsNonExpired() + { + return true; + } + + /** + * 是否可用 ,禁用的用户不能身份验证 + * + * @return + */ + @JSONField(serialize = false) + @Override + public boolean isEnabled() + { + return true; + } + + public Long getLoginTime() + { + return loginTime; + } + + public void setLoginTime(Long loginTime) + { + this.loginTime = loginTime; + } + + public String getIpaddr() + { + return ipaddr; + } + + public void setIpaddr(String ipaddr) + { + this.ipaddr = ipaddr; + } + + public String getLoginLocation() + { + return loginLocation; + } + + public void setLoginLocation(String loginLocation) + { + this.loginLocation = loginLocation; + } + + public String getBrowser() + { + return browser; + } + + public void setBrowser(String browser) + { + this.browser = browser; + } + + public String getOs() + { + return os; + } + + public void setOs(String os) + { + this.os = os; + } + + public Long getExpireTime() + { + return expireTime; + } + + public void setExpireTime(Long expireTime) + { + this.expireTime = expireTime; + } + + public Set getPermissions() + { + return permissions; + } + + public void setPermissions(Set permissions) + { + this.permissions = permissions; + } + + public SysUser getUser() + { + return user; + } + + public void setUser(SysUser user) + { + this.user = user; + } + + @Override + public Collection getAuthorities() + { + return null; + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/core/domain/model/RegisterBody.java b/zzyl-common/src/main/java/com/zzyl/common/core/domain/model/RegisterBody.java new file mode 100644 index 0000000..7d526f9 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/core/domain/model/RegisterBody.java @@ -0,0 +1,11 @@ +package com.zzyl.common.core.domain.model; + +/** + * 用户注册对象 + * + * @author ruoyi + */ +public class RegisterBody extends LoginBody +{ + +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/core/page/PageDomain.java b/zzyl-common/src/main/java/com/zzyl/common/core/page/PageDomain.java new file mode 100644 index 0000000..d781ca9 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/core/page/PageDomain.java @@ -0,0 +1,101 @@ +package com.zzyl.common.core.page; + +import com.zzyl.common.utils.StringUtils; + +/** + * 分页数据 + * + * @author ruoyi + */ +public class PageDomain +{ + /** 当前记录起始索引 */ + private Integer pageNum; + + /** 每页显示记录数 */ + private Integer pageSize; + + /** 排序列 */ + private String orderByColumn; + + /** 排序的方向desc或者asc */ + private String isAsc = "asc"; + + /** 分页参数合理化 */ + private Boolean reasonable = true; + + public String getOrderBy() + { + if (StringUtils.isEmpty(orderByColumn)) + { + return ""; + } + return StringUtils.toUnderScoreCase(orderByColumn) + " " + isAsc; + } + + public Integer getPageNum() + { + return pageNum; + } + + public void setPageNum(Integer pageNum) + { + this.pageNum = pageNum; + } + + public Integer getPageSize() + { + return pageSize; + } + + public void setPageSize(Integer pageSize) + { + this.pageSize = pageSize; + } + + public String getOrderByColumn() + { + return orderByColumn; + } + + public void setOrderByColumn(String orderByColumn) + { + this.orderByColumn = orderByColumn; + } + + public String getIsAsc() + { + return isAsc; + } + + public void setIsAsc(String isAsc) + { + if (StringUtils.isNotEmpty(isAsc)) + { + // 兼容前端排序类型 + if ("ascending".equals(isAsc)) + { + isAsc = "asc"; + } + else if ("descending".equals(isAsc)) + { + isAsc = "desc"; + } + this.isAsc = isAsc; + } + } + + public Boolean getReasonable() + { + if (StringUtils.isNull(reasonable)) + { + return Boolean.TRUE; + } + return reasonable; + } + + public void setReasonable(Boolean reasonable) + { + this.reasonable = reasonable; + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/core/page/TableDataInfo.java b/zzyl-common/src/main/java/com/zzyl/common/core/page/TableDataInfo.java new file mode 100644 index 0000000..ec26bfe --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/core/page/TableDataInfo.java @@ -0,0 +1,85 @@ +package com.zzyl.common.core.page; + +import java.io.Serializable; +import java.util.List; + +/** + * 表格分页数据对象 + * + * @author ruoyi + */ +public class TableDataInfo implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** 总记录数 */ + private long total; + + /** 列表数据 */ + private List rows; + + /** 消息状态码 */ + private int code; + + /** 消息内容 */ + private String msg; + + /** + * 表格数据对象 + */ + public TableDataInfo() + { + } + + /** + * 分页 + * + * @param list 列表数据 + * @param total 总记录数 + */ + public TableDataInfo(List list, int total) + { + this.rows = list; + this.total = total; + } + + public long getTotal() + { + return total; + } + + public void setTotal(long total) + { + this.total = total; + } + + public List getRows() + { + return rows; + } + + public void setRows(List rows) + { + this.rows = rows; + } + + public int getCode() + { + return code; + } + + public void setCode(int code) + { + this.code = code; + } + + public String getMsg() + { + return msg; + } + + public void setMsg(String msg) + { + this.msg = msg; + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/core/page/TableSupport.java b/zzyl-common/src/main/java/com/zzyl/common/core/page/TableSupport.java new file mode 100644 index 0000000..dc7cecc --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/core/page/TableSupport.java @@ -0,0 +1,56 @@ +package com.zzyl.common.core.page; + +import com.zzyl.common.core.text.Convert; +import com.zzyl.common.utils.ServletUtils; + +/** + * 表格数据处理 + * + * @author ruoyi + */ +public class TableSupport +{ + /** + * 当前记录起始索引 + */ + public static final String PAGE_NUM = "pageNum"; + + /** + * 每页显示记录数 + */ + public static final String PAGE_SIZE = "pageSize"; + + /** + * 排序列 + */ + public static final String ORDER_BY_COLUMN = "orderByColumn"; + + /** + * 排序的方向 "desc" 或者 "asc". + */ + public static final String IS_ASC = "isAsc"; + + /** + * 分页参数合理化 + */ + public static final String REASONABLE = "reasonable"; + + /** + * 封装分页对象 + */ + public static PageDomain getPageDomain() + { + PageDomain pageDomain = new PageDomain(); + pageDomain.setPageNum(Convert.toInt(ServletUtils.getParameter(PAGE_NUM), 1)); + pageDomain.setPageSize(Convert.toInt(ServletUtils.getParameter(PAGE_SIZE), 10)); + pageDomain.setOrderByColumn(ServletUtils.getParameter(ORDER_BY_COLUMN)); + pageDomain.setIsAsc(ServletUtils.getParameter(IS_ASC)); + pageDomain.setReasonable(ServletUtils.getParameterToBool(REASONABLE)); + return pageDomain; + } + + public static PageDomain buildPageRequest() + { + return getPageDomain(); + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/core/redis/RedisCache.java b/zzyl-common/src/main/java/com/zzyl/common/core/redis/RedisCache.java new file mode 100644 index 0000000..17232ff --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/core/redis/RedisCache.java @@ -0,0 +1,268 @@ +package com.zzyl.common.core.redis; + +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.BoundSetOperations; +import org.springframework.data.redis.core.HashOperations; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.ValueOperations; +import org.springframework.stereotype.Component; + +/** + * spring redis 工具类 + * + * @author ruoyi + **/ +@SuppressWarnings(value = { "unchecked", "rawtypes" }) +@Component +public class RedisCache +{ + @Autowired + public RedisTemplate redisTemplate; + + /** + * 缓存基本的对象,Integer、String、实体类等 + * + * @param key 缓存的键值 + * @param value 缓存的值 + */ + public void setCacheObject(final String key, final T value) + { + redisTemplate.opsForValue().set(key, value); + } + + /** + * 缓存基本的对象,Integer、String、实体类等 + * + * @param key 缓存的键值 + * @param value 缓存的值 + * @param timeout 时间 + * @param timeUnit 时间颗粒度 + */ + public void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit) + { + redisTemplate.opsForValue().set(key, value, timeout, timeUnit); + } + + /** + * 设置有效时间 + * + * @param key Redis键 + * @param timeout 超时时间 + * @return true=设置成功;false=设置失败 + */ + public boolean expire(final String key, final long timeout) + { + return expire(key, timeout, TimeUnit.SECONDS); + } + + /** + * 设置有效时间 + * + * @param key Redis键 + * @param timeout 超时时间 + * @param unit 时间单位 + * @return true=设置成功;false=设置失败 + */ + public boolean expire(final String key, final long timeout, final TimeUnit unit) + { + return redisTemplate.expire(key, timeout, unit); + } + + /** + * 获取有效时间 + * + * @param key Redis键 + * @return 有效时间 + */ + public long getExpire(final String key) + { + return redisTemplate.getExpire(key); + } + + /** + * 判断 key是否存在 + * + * @param key 键 + * @return true 存在 false不存在 + */ + public Boolean hasKey(String key) + { + return redisTemplate.hasKey(key); + } + + /** + * 获得缓存的基本对象。 + * + * @param key 缓存键值 + * @return 缓存键值对应的数据 + */ + public T getCacheObject(final String key) + { + ValueOperations operation = redisTemplate.opsForValue(); + return operation.get(key); + } + + /** + * 删除单个对象 + * + * @param key + */ + public boolean deleteObject(final String key) + { + return redisTemplate.delete(key); + } + + /** + * 删除集合对象 + * + * @param collection 多个对象 + * @return + */ + public boolean deleteObject(final Collection collection) + { + return redisTemplate.delete(collection) > 0; + } + + /** + * 缓存List数据 + * + * @param key 缓存的键值 + * @param dataList 待缓存的List数据 + * @return 缓存的对象 + */ + public long setCacheList(final String key, final List dataList) + { + Long count = redisTemplate.opsForList().rightPushAll(key, dataList); + return count == null ? 0 : count; + } + + /** + * 获得缓存的list对象 + * + * @param key 缓存的键值 + * @return 缓存键值对应的数据 + */ + public List getCacheList(final String key) + { + return redisTemplate.opsForList().range(key, 0, -1); + } + + /** + * 缓存Set + * + * @param key 缓存键值 + * @param dataSet 缓存的数据 + * @return 缓存数据的对象 + */ + public BoundSetOperations setCacheSet(final String key, final Set dataSet) + { + BoundSetOperations setOperation = redisTemplate.boundSetOps(key); + Iterator it = dataSet.iterator(); + while (it.hasNext()) + { + setOperation.add(it.next()); + } + return setOperation; + } + + /** + * 获得缓存的set + * + * @param key + * @return + */ + public Set getCacheSet(final String key) + { + return redisTemplate.opsForSet().members(key); + } + + /** + * 缓存Map + * + * @param key + * @param dataMap + */ + public void setCacheMap(final String key, final Map dataMap) + { + if (dataMap != null) { + redisTemplate.opsForHash().putAll(key, dataMap); + } + } + + /** + * 获得缓存的Map + * + * @param key + * @return + */ + public Map getCacheMap(final String key) + { + return redisTemplate.opsForHash().entries(key); + } + + /** + * 往Hash中存入数据 + * + * @param key Redis键 + * @param hKey Hash键 + * @param value 值 + */ + public void setCacheMapValue(final String key, final String hKey, final T value) + { + redisTemplate.opsForHash().put(key, hKey, value); + } + + /** + * 获取Hash中的数据 + * + * @param key Redis键 + * @param hKey Hash键 + * @return Hash中的对象 + */ + public T getCacheMapValue(final String key, final String hKey) + { + HashOperations opsForHash = redisTemplate.opsForHash(); + return opsForHash.get(key, hKey); + } + + /** + * 获取多个Hash中的数据 + * + * @param key Redis键 + * @param hKeys Hash键集合 + * @return Hash对象集合 + */ + public List getMultiCacheMapValue(final String key, final Collection hKeys) + { + return redisTemplate.opsForHash().multiGet(key, hKeys); + } + + /** + * 删除Hash中的某条数据 + * + * @param key Redis键 + * @param hKey Hash键 + * @return 是否成功 + */ + public boolean deleteCacheMapValue(final String key, final String hKey) + { + return redisTemplate.opsForHash().delete(key, hKey) > 0; + } + + /** + * 获得缓存的基本对象列表 + * + * @param pattern 字符串前缀 + * @return 对象列表 + */ + public Collection keys(final String pattern) + { + return redisTemplate.keys(pattern); + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/core/text/CharsetKit.java b/zzyl-common/src/main/java/com/zzyl/common/core/text/CharsetKit.java new file mode 100644 index 0000000..1a20c66 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/core/text/CharsetKit.java @@ -0,0 +1,86 @@ +package com.zzyl.common.core.text; + +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import com.zzyl.common.utils.StringUtils; + +/** + * 字符集工具类 + * + * @author ruoyi + */ +public class CharsetKit +{ + /** ISO-8859-1 */ + public static final String ISO_8859_1 = "ISO-8859-1"; + /** UTF-8 */ + public static final String UTF_8 = "UTF-8"; + /** GBK */ + public static final String GBK = "GBK"; + + /** ISO-8859-1 */ + public static final Charset CHARSET_ISO_8859_1 = Charset.forName(ISO_8859_1); + /** UTF-8 */ + public static final Charset CHARSET_UTF_8 = Charset.forName(UTF_8); + /** GBK */ + public static final Charset CHARSET_GBK = Charset.forName(GBK); + + /** + * 转换为Charset对象 + * + * @param charset 字符集,为空则返回默认字符集 + * @return Charset + */ + public static Charset charset(String charset) + { + return StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset); + } + + /** + * 转换字符串的字符集编码 + * + * @param source 字符串 + * @param srcCharset 源字符集,默认ISO-8859-1 + * @param destCharset 目标字符集,默认UTF-8 + * @return 转换后的字符集 + */ + public static String convert(String source, String srcCharset, String destCharset) + { + return convert(source, Charset.forName(srcCharset), Charset.forName(destCharset)); + } + + /** + * 转换字符串的字符集编码 + * + * @param source 字符串 + * @param srcCharset 源字符集,默认ISO-8859-1 + * @param destCharset 目标字符集,默认UTF-8 + * @return 转换后的字符集 + */ + public static String convert(String source, Charset srcCharset, Charset destCharset) + { + if (null == srcCharset) + { + srcCharset = StandardCharsets.ISO_8859_1; + } + + if (null == destCharset) + { + destCharset = StandardCharsets.UTF_8; + } + + if (StringUtils.isEmpty(source) || srcCharset.equals(destCharset)) + { + return source; + } + return new String(source.getBytes(srcCharset), destCharset); + } + + /** + * @return 系统字符集编码 + */ + public static String systemCharset() + { + return Charset.defaultCharset().name(); + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/core/text/Convert.java b/zzyl-common/src/main/java/com/zzyl/common/core/text/Convert.java new file mode 100644 index 0000000..f84a506 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/core/text/Convert.java @@ -0,0 +1,1010 @@ +package com.zzyl.common.core.text; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.math.RoundingMode; +import java.nio.ByteBuffer; +import java.nio.charset.Charset; +import java.text.NumberFormat; +import java.util.Set; +import com.zzyl.common.utils.StringUtils; +import org.apache.commons.lang3.ArrayUtils; + +/** + * 类型转换器 + * + * @author ruoyi + */ +public class Convert +{ + /** + * 转换为字符串
+ * 如果给定的值为null,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static String toStr(Object value, String defaultValue) + { + if (null == value) + { + return defaultValue; + } + if (value instanceof String) + { + return (String) value; + } + return value.toString(); + } + + /** + * 转换为字符串
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static String toStr(Object value) + { + return toStr(value, null); + } + + /** + * 转换为字符
+ * 如果给定的值为null,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Character toChar(Object value, Character defaultValue) + { + if (null == value) + { + return defaultValue; + } + if (value instanceof Character) + { + return (Character) value; + } + + final String valueStr = toStr(value, null); + return StringUtils.isEmpty(valueStr) ? defaultValue : valueStr.charAt(0); + } + + /** + * 转换为字符
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Character toChar(Object value) + { + return toChar(value, null); + } + + /** + * 转换为byte
+ * 如果给定的值为null,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Byte toByte(Object value, Byte defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Byte) + { + return (Byte) value; + } + if (value instanceof Number) + { + return ((Number) value).byteValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return Byte.parseByte(valueStr); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为byte
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Byte toByte(Object value) + { + return toByte(value, null); + } + + /** + * 转换为Short
+ * 如果给定的值为null,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Short toShort(Object value, Short defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Short) + { + return (Short) value; + } + if (value instanceof Number) + { + return ((Number) value).shortValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return Short.parseShort(valueStr.trim()); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为Short
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Short toShort(Object value) + { + return toShort(value, null); + } + + /** + * 转换为Number
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Number toNumber(Object value, Number defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Number) + { + return (Number) value; + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return NumberFormat.getInstance().parse(valueStr); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为Number
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Number toNumber(Object value) + { + return toNumber(value, null); + } + + /** + * 转换为int
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Integer toInt(Object value, Integer defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Integer) + { + return (Integer) value; + } + if (value instanceof Number) + { + return ((Number) value).intValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return Integer.parseInt(valueStr.trim()); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为int
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Integer toInt(Object value) + { + return toInt(value, null); + } + + /** + * 转换为Integer数组
+ * + * @param str 被转换的值 + * @return 结果 + */ + public static Integer[] toIntArray(String str) + { + return toIntArray(",", str); + } + + /** + * 转换为Long数组
+ * + * @param str 被转换的值 + * @return 结果 + */ + public static Long[] toLongArray(String str) + { + return toLongArray(",", str); + } + + /** + * 转换为Integer数组
+ * + * @param split 分隔符 + * @param split 被转换的值 + * @return 结果 + */ + public static Integer[] toIntArray(String split, String str) + { + if (StringUtils.isEmpty(str)) + { + return new Integer[] {}; + } + String[] arr = str.split(split); + final Integer[] ints = new Integer[arr.length]; + for (int i = 0; i < arr.length; i++) + { + final Integer v = toInt(arr[i], 0); + ints[i] = v; + } + return ints; + } + + /** + * 转换为Long数组
+ * + * @param split 分隔符 + * @param str 被转换的值 + * @return 结果 + */ + public static Long[] toLongArray(String split, String str) + { + if (StringUtils.isEmpty(str)) + { + return new Long[] {}; + } + String[] arr = str.split(split); + final Long[] longs = new Long[arr.length]; + for (int i = 0; i < arr.length; i++) + { + final Long v = toLong(arr[i], null); + longs[i] = v; + } + return longs; + } + + /** + * 转换为String数组
+ * + * @param str 被转换的值 + * @return 结果 + */ + public static String[] toStrArray(String str) + { + if (StringUtils.isEmpty(str)) + { + return new String[] {}; + } + return toStrArray(",", str); + } + + /** + * 转换为String数组
+ * + * @param split 分隔符 + * @param split 被转换的值 + * @return 结果 + */ + public static String[] toStrArray(String split, String str) + { + return str.split(split); + } + + /** + * 转换为long
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Long toLong(Object value, Long defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Long) + { + return (Long) value; + } + if (value instanceof Number) + { + return ((Number) value).longValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + // 支持科学计数法 + return new BigDecimal(valueStr.trim()).longValue(); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为long
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Long toLong(Object value) + { + return toLong(value, null); + } + + /** + * 转换为double
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Double toDouble(Object value, Double defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Double) + { + return (Double) value; + } + if (value instanceof Number) + { + return ((Number) value).doubleValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + // 支持科学计数法 + return new BigDecimal(valueStr.trim()).doubleValue(); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为double
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Double toDouble(Object value) + { + return toDouble(value, null); + } + + /** + * 转换为Float
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Float toFloat(Object value, Float defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Float) + { + return (Float) value; + } + if (value instanceof Number) + { + return ((Number) value).floatValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return Float.parseFloat(valueStr.trim()); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为Float
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Float toFloat(Object value) + { + return toFloat(value, null); + } + + /** + * 转换为boolean
+ * String支持的值为:true、false、yes、ok、no,1,0 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Boolean toBool(Object value, Boolean defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Boolean) + { + return (Boolean) value; + } + String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + valueStr = valueStr.trim().toLowerCase(); + switch (valueStr) + { + case "true": + case "yes": + case "ok": + case "1": + return true; + case "false": + case "no": + case "0": + return false; + default: + return defaultValue; + } + } + + /** + * 转换为boolean
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Boolean toBool(Object value) + { + return toBool(value, null); + } + + /** + * 转换为Enum对象
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * + * @param clazz Enum的Class + * @param value 值 + * @param defaultValue 默认值 + * @return Enum + */ + public static > E toEnum(Class clazz, Object value, E defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (clazz.isAssignableFrom(value.getClass())) + { + @SuppressWarnings("unchecked") + E myE = (E) value; + return myE; + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return Enum.valueOf(clazz, valueStr); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为Enum对象
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * + * @param clazz Enum的Class + * @param value 值 + * @return Enum + */ + public static > E toEnum(Class clazz, Object value) + { + return toEnum(clazz, value, null); + } + + /** + * 转换为BigInteger
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static BigInteger toBigInteger(Object value, BigInteger defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof BigInteger) + { + return (BigInteger) value; + } + if (value instanceof Long) + { + return BigInteger.valueOf((Long) value); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return new BigInteger(valueStr); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为BigInteger
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static BigInteger toBigInteger(Object value) + { + return toBigInteger(value, null); + } + + /** + * 转换为BigDecimal
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static BigDecimal toBigDecimal(Object value, BigDecimal defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof BigDecimal) + { + return (BigDecimal) value; + } + if (value instanceof Long) + { + return new BigDecimal((Long) value); + } + if (value instanceof Double) + { + return BigDecimal.valueOf((Double) value); + } + if (value instanceof Integer) + { + return new BigDecimal((Integer) value); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return new BigDecimal(valueStr); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为BigDecimal
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static BigDecimal toBigDecimal(Object value) + { + return toBigDecimal(value, null); + } + + /** + * 将对象转为字符串
+ * 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法 + * + * @param obj 对象 + * @return 字符串 + */ + public static String utf8Str(Object obj) + { + return str(obj, CharsetKit.CHARSET_UTF_8); + } + + /** + * 将对象转为字符串
+ * 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法 + * + * @param obj 对象 + * @param charsetName 字符集 + * @return 字符串 + */ + public static String str(Object obj, String charsetName) + { + return str(obj, Charset.forName(charsetName)); + } + + /** + * 将对象转为字符串
+ * 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法 + * + * @param obj 对象 + * @param charset 字符集 + * @return 字符串 + */ + public static String str(Object obj, Charset charset) + { + if (null == obj) + { + return null; + } + + if (obj instanceof String) + { + return (String) obj; + } + else if (obj instanceof byte[]) + { + return str((byte[]) obj, charset); + } + else if (obj instanceof Byte[]) + { + byte[] bytes = ArrayUtils.toPrimitive((Byte[]) obj); + return str(bytes, charset); + } + else if (obj instanceof ByteBuffer) + { + return str((ByteBuffer) obj, charset); + } + return obj.toString(); + } + + /** + * 将byte数组转为字符串 + * + * @param bytes byte数组 + * @param charset 字符集 + * @return 字符串 + */ + public static String str(byte[] bytes, String charset) + { + return str(bytes, StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset)); + } + + /** + * 解码字节码 + * + * @param data 字符串 + * @param charset 字符集,如果此字段为空,则解码的结果取决于平台 + * @return 解码后的字符串 + */ + public static String str(byte[] data, Charset charset) + { + if (data == null) + { + return null; + } + + if (null == charset) + { + return new String(data); + } + return new String(data, charset); + } + + /** + * 将编码的byteBuffer数据转换为字符串 + * + * @param data 数据 + * @param charset 字符集,如果为空使用当前系统字符集 + * @return 字符串 + */ + public static String str(ByteBuffer data, String charset) + { + if (data == null) + { + return null; + } + + return str(data, Charset.forName(charset)); + } + + /** + * 将编码的byteBuffer数据转换为字符串 + * + * @param data 数据 + * @param charset 字符集,如果为空使用当前系统字符集 + * @return 字符串 + */ + public static String str(ByteBuffer data, Charset charset) + { + if (null == charset) + { + charset = Charset.defaultCharset(); + } + return charset.decode(data).toString(); + } + + // ----------------------------------------------------------------------- 全角半角转换 + /** + * 半角转全角 + * + * @param input String. + * @return 全角字符串. + */ + public static String toSBC(String input) + { + return toSBC(input, null); + } + + /** + * 半角转全角 + * + * @param input String + * @param notConvertSet 不替换的字符集合 + * @return 全角字符串. + */ + public static String toSBC(String input, Set notConvertSet) + { + char[] c = input.toCharArray(); + for (int i = 0; i < c.length; i++) + { + if (null != notConvertSet && notConvertSet.contains(c[i])) + { + // 跳过不替换的字符 + continue; + } + + if (c[i] == ' ') + { + c[i] = '\u3000'; + } + else if (c[i] < '\177') + { + c[i] = (char) (c[i] + 65248); + + } + } + return new String(c); + } + + /** + * 全角转半角 + * + * @param input String. + * @return 半角字符串 + */ + public static String toDBC(String input) + { + return toDBC(input, null); + } + + /** + * 替换全角为半角 + * + * @param text 文本 + * @param notConvertSet 不替换的字符集合 + * @return 替换后的字符 + */ + public static String toDBC(String text, Set notConvertSet) + { + char[] c = text.toCharArray(); + for (int i = 0; i < c.length; i++) + { + if (null != notConvertSet && notConvertSet.contains(c[i])) + { + // 跳过不替换的字符 + continue; + } + + if (c[i] == '\u3000') + { + c[i] = ' '; + } + else if (c[i] > '\uFF00' && c[i] < '\uFF5F') + { + c[i] = (char) (c[i] - 65248); + } + } + String returnString = new String(c); + + return returnString; + } + + /** + * 数字金额大写转换 先写个完整的然后将如零拾替换成零 + * + * @param n 数字 + * @return 中文大写数字 + */ + public static String digitUppercase(double n) + { + String[] fraction = { "角", "分" }; + String[] digit = { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" }; + String[][] unit = { { "元", "万", "亿" }, { "", "拾", "佰", "仟" } }; + + String head = n < 0 ? "负" : ""; + n = Math.abs(n); + + String s = ""; + for (int i = 0; i < fraction.length; i++) + { + // 优化double计算精度丢失问题 + BigDecimal nNum = new BigDecimal(n); + BigDecimal decimal = new BigDecimal(10); + BigDecimal scale = nNum.multiply(decimal).setScale(2, RoundingMode.HALF_EVEN); + double d = scale.doubleValue(); + s += (digit[(int) (Math.floor(d * Math.pow(10, i)) % 10)] + fraction[i]).replaceAll("(零.)+", ""); + } + if (s.length() < 1) + { + s = "整"; + } + int integerPart = (int) Math.floor(n); + + for (int i = 0; i < unit[0].length && integerPart > 0; i++) + { + String p = ""; + for (int j = 0; j < unit[1].length && n > 0; j++) + { + p = digit[integerPart % 10] + unit[1][j] + p; + integerPart = integerPart / 10; + } + s = p.replaceAll("(零.)*零$", "").replaceAll("^$", "零") + unit[0][i] + s; + } + return head + s.replaceAll("(零.)*零元", "元").replaceFirst("(零.)+", "").replaceAll("(零.)+", "零").replaceAll("^整$", "零元整"); + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/core/text/StrFormatter.java b/zzyl-common/src/main/java/com/zzyl/common/core/text/StrFormatter.java new file mode 100644 index 0000000..59ca25a --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/core/text/StrFormatter.java @@ -0,0 +1,92 @@ +package com.zzyl.common.core.text; + +import com.zzyl.common.utils.StringUtils; + +/** + * 字符串格式化 + * + * @author ruoyi + */ +public class StrFormatter +{ + public static final String EMPTY_JSON = "{}"; + public static final char C_BACKSLASH = '\\'; + public static final char C_DELIM_START = '{'; + public static final char C_DELIM_END = '}'; + + /** + * 格式化字符串
+ * 此方法只是简单将占位符 {} 按照顺序替换为参数
+ * 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可
+ * 例:
+ * 通常使用:format("this is {} for {}", "a", "b") -> this is a for b
+ * 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a
+ * 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b
+ * + * @param strPattern 字符串模板 + * @param argArray 参数列表 + * @return 结果 + */ + public static String format(final String strPattern, final Object... argArray) + { + if (StringUtils.isEmpty(strPattern) || StringUtils.isEmpty(argArray)) + { + return strPattern; + } + final int strPatternLength = strPattern.length(); + + // 初始化定义好的长度以获得更好的性能 + StringBuilder sbuf = new StringBuilder(strPatternLength + 50); + + int handledPosition = 0; + int delimIndex;// 占位符所在位置 + for (int argIndex = 0; argIndex < argArray.length; argIndex++) + { + delimIndex = strPattern.indexOf(EMPTY_JSON, handledPosition); + if (delimIndex == -1) + { + if (handledPosition == 0) + { + return strPattern; + } + else + { // 字符串模板剩余部分不再包含占位符,加入剩余部分后返回结果 + sbuf.append(strPattern, handledPosition, strPatternLength); + return sbuf.toString(); + } + } + else + { + if (delimIndex > 0 && strPattern.charAt(delimIndex - 1) == C_BACKSLASH) + { + if (delimIndex > 1 && strPattern.charAt(delimIndex - 2) == C_BACKSLASH) + { + // 转义符之前还有一个转义符,占位符依旧有效 + sbuf.append(strPattern, handledPosition, delimIndex - 1); + sbuf.append(Convert.utf8Str(argArray[argIndex])); + handledPosition = delimIndex + 2; + } + else + { + // 占位符被转义 + argIndex--; + sbuf.append(strPattern, handledPosition, delimIndex - 1); + sbuf.append(C_DELIM_START); + handledPosition = delimIndex + 1; + } + } + else + { + // 正常占位符 + sbuf.append(strPattern, handledPosition, delimIndex); + sbuf.append(Convert.utf8Str(argArray[argIndex])); + handledPosition = delimIndex + 2; + } + } + } + // 加入最后一个占位符后所有的字符 + sbuf.append(strPattern, handledPosition, strPattern.length()); + + return sbuf.toString(); + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/enums/BusinessStatus.java b/zzyl-common/src/main/java/com/zzyl/common/enums/BusinessStatus.java new file mode 100644 index 0000000..3806101 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/enums/BusinessStatus.java @@ -0,0 +1,20 @@ +package com.zzyl.common.enums; + +/** + * 操作状态 + * + * @author ruoyi + * + */ +public enum BusinessStatus +{ + /** + * 成功 + */ + SUCCESS, + + /** + * 失败 + */ + FAIL, +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/enums/BusinessType.java b/zzyl-common/src/main/java/com/zzyl/common/enums/BusinessType.java new file mode 100644 index 0000000..fb993b3 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/enums/BusinessType.java @@ -0,0 +1,59 @@ +package com.zzyl.common.enums; + +/** + * 业务操作类型 + * + * @author ruoyi + */ +public enum BusinessType +{ + /** + * 其它 + */ + OTHER, + + /** + * 新增 + */ + INSERT, + + /** + * 修改 + */ + UPDATE, + + /** + * 删除 + */ + DELETE, + + /** + * 授权 + */ + GRANT, + + /** + * 导出 + */ + EXPORT, + + /** + * 导入 + */ + IMPORT, + + /** + * 强退 + */ + FORCE, + + /** + * 生成代码 + */ + GENCODE, + + /** + * 清空数据 + */ + CLEAN, +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/enums/DataSourceType.java b/zzyl-common/src/main/java/com/zzyl/common/enums/DataSourceType.java new file mode 100644 index 0000000..efedbae --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/enums/DataSourceType.java @@ -0,0 +1,19 @@ +package com.zzyl.common.enums; + +/** + * 数据源 + * + * @author ruoyi + */ +public enum DataSourceType +{ + /** + * 主库 + */ + MASTER, + + /** + * 从库 + */ + SLAVE +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/enums/DesensitizedType.java b/zzyl-common/src/main/java/com/zzyl/common/enums/DesensitizedType.java new file mode 100644 index 0000000..d596de0 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/enums/DesensitizedType.java @@ -0,0 +1,59 @@ +package com.zzyl.common.enums; + +import java.util.function.Function; +import com.zzyl.common.utils.DesensitizedUtil; + +/** + * 脱敏类型 + * + * @author ruoyi + */ +public enum DesensitizedType +{ + /** + * 姓名,第2位星号替换 + */ + USERNAME(s -> s.replaceAll("(\\S)\\S(\\S*)", "$1*$2")), + + /** + * 密码,全部字符都用*代替 + */ + PASSWORD(DesensitizedUtil::password), + + /** + * 身份证,中间10位星号替换 + */ + ID_CARD(s -> s.replaceAll("(\\d{4})\\d{10}(\\d{3}[Xx]|\\d{4})", "$1** **** ****$2")), + + /** + * 手机号,中间4位星号替换 + */ + PHONE(s -> s.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2")), + + /** + * 电子邮箱,仅显示第一个字母和@后面的地址显示,其他星号替换 + */ + EMAIL(s -> s.replaceAll("(^.)[^@]*(@.*$)", "$1****$2")), + + /** + * 银行卡号,保留最后4位,其他星号替换 + */ + BANK_CARD(s -> s.replaceAll("\\d{15}(\\d{3})", "**** **** **** **** $1")), + + /** + * 车牌号码,包含普通车辆、新能源车辆 + */ + CAR_LICENSE(DesensitizedUtil::carLicense); + + private final Function desensitizer; + + DesensitizedType(Function desensitizer) + { + this.desensitizer = desensitizer; + } + + public Function desensitizer() + { + return desensitizer; + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/enums/HttpMethod.java b/zzyl-common/src/main/java/com/zzyl/common/enums/HttpMethod.java new file mode 100644 index 0000000..a7c5d13 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/enums/HttpMethod.java @@ -0,0 +1,36 @@ +package com.zzyl.common.enums; + +import java.util.HashMap; +import java.util.Map; +import org.springframework.lang.Nullable; + +/** + * 请求方式 + * + * @author ruoyi + */ +public enum HttpMethod +{ + GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE; + + private static final Map mappings = new HashMap<>(16); + + static + { + for (HttpMethod httpMethod : values()) + { + mappings.put(httpMethod.name(), httpMethod); + } + } + + @Nullable + public static HttpMethod resolve(@Nullable String method) + { + return (method != null ? mappings.get(method) : null); + } + + public boolean matches(String method) + { + return (this == resolve(method)); + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/enums/LimitType.java b/zzyl-common/src/main/java/com/zzyl/common/enums/LimitType.java new file mode 100644 index 0000000..2a1d4d1 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/enums/LimitType.java @@ -0,0 +1,20 @@ +package com.zzyl.common.enums; + +/** + * 限流类型 + * + * @author ruoyi + */ + +public enum LimitType +{ + /** + * 默认策略全局限流 + */ + DEFAULT, + + /** + * 根据请求者IP进行限流 + */ + IP +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/enums/OperatorType.java b/zzyl-common/src/main/java/com/zzyl/common/enums/OperatorType.java new file mode 100644 index 0000000..6b38128 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/enums/OperatorType.java @@ -0,0 +1,24 @@ +package com.zzyl.common.enums; + +/** + * 操作人类别 + * + * @author ruoyi + */ +public enum OperatorType +{ + /** + * 其它 + */ + OTHER, + + /** + * 后台用户 + */ + MANAGE, + + /** + * 手机端用户 + */ + MOBILE +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/enums/UserStatus.java b/zzyl-common/src/main/java/com/zzyl/common/enums/UserStatus.java new file mode 100644 index 0000000..c2de8f1 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/enums/UserStatus.java @@ -0,0 +1,30 @@ +package com.zzyl.common.enums; + +/** + * 用户状态 + * + * @author ruoyi + */ +public enum UserStatus +{ + OK("0", "正常"), DISABLE("1", "停用"), DELETED("2", "删除"); + + private final String code; + private final String info; + + UserStatus(String code, String info) + { + this.code = code; + this.info = info; + } + + public String getCode() + { + return code; + } + + public String getInfo() + { + return info; + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/exception/DemoModeException.java b/zzyl-common/src/main/java/com/zzyl/common/exception/DemoModeException.java new file mode 100644 index 0000000..c209fce --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/exception/DemoModeException.java @@ -0,0 +1,15 @@ +package com.zzyl.common.exception; + +/** + * 演示模式异常 + * + * @author ruoyi + */ +public class DemoModeException extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + public DemoModeException() + { + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/exception/GlobalException.java b/zzyl-common/src/main/java/com/zzyl/common/exception/GlobalException.java new file mode 100644 index 0000000..73bb1fd --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/exception/GlobalException.java @@ -0,0 +1,58 @@ +package com.zzyl.common.exception; + +/** + * 全局异常 + * + * @author ruoyi + */ +public class GlobalException extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + /** + * 错误提示 + */ + private String message; + + /** + * 错误明细,内部调试错误 + * + * 和 {@link CommonResult#getDetailMessage()} 一致的设计 + */ + private String detailMessage; + + /** + * 空构造方法,避免反序列化问题 + */ + public GlobalException() + { + } + + public GlobalException(String message) + { + this.message = message; + } + + public String getDetailMessage() + { + return detailMessage; + } + + public GlobalException setDetailMessage(String detailMessage) + { + this.detailMessage = detailMessage; + return this; + } + + @Override + public String getMessage() + { + return message; + } + + public GlobalException setMessage(String message) + { + this.message = message; + return this; + } +} \ No newline at end of file diff --git a/zzyl-common/src/main/java/com/zzyl/common/exception/ServiceException.java b/zzyl-common/src/main/java/com/zzyl/common/exception/ServiceException.java new file mode 100644 index 0000000..fd215f5 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/exception/ServiceException.java @@ -0,0 +1,74 @@ +package com.zzyl.common.exception; + +/** + * 业务异常 + * + * @author ruoyi + */ +public final class ServiceException extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + /** + * 错误码 + */ + private Integer code; + + /** + * 错误提示 + */ + private String message; + + /** + * 错误明细,内部调试错误 + * + * 和 {@link CommonResult#getDetailMessage()} 一致的设计 + */ + private String detailMessage; + + /** + * 空构造方法,避免反序列化问题 + */ + public ServiceException() + { + } + + public ServiceException(String message) + { + this.message = message; + } + + public ServiceException(String message, Integer code) + { + this.message = message; + this.code = code; + } + + public String getDetailMessage() + { + return detailMessage; + } + + @Override + public String getMessage() + { + return message; + } + + public Integer getCode() + { + return code; + } + + public ServiceException setMessage(String message) + { + this.message = message; + return this; + } + + public ServiceException setDetailMessage(String detailMessage) + { + this.detailMessage = detailMessage; + return this; + } +} \ No newline at end of file diff --git a/zzyl-common/src/main/java/com/zzyl/common/exception/UtilException.java b/zzyl-common/src/main/java/com/zzyl/common/exception/UtilException.java new file mode 100644 index 0000000..b1a589f --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/exception/UtilException.java @@ -0,0 +1,26 @@ +package com.zzyl.common.exception; + +/** + * 工具类异常 + * + * @author ruoyi + */ +public class UtilException extends RuntimeException +{ + private static final long serialVersionUID = 8247610319171014183L; + + public UtilException(Throwable e) + { + super(e.getMessage(), e); + } + + public UtilException(String message) + { + super(message); + } + + public UtilException(String message, Throwable throwable) + { + super(message, throwable); + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/exception/base/BaseException.java b/zzyl-common/src/main/java/com/zzyl/common/exception/base/BaseException.java new file mode 100644 index 0000000..ed8750e --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/exception/base/BaseException.java @@ -0,0 +1,97 @@ +package com.zzyl.common.exception.base; + +import com.zzyl.common.utils.MessageUtils; +import com.zzyl.common.utils.StringUtils; + +/** + * 基础异常 + * + * @author ruoyi + */ +public class BaseException extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + /** + * 所属模块 + */ + private String module; + + /** + * 错误码 + */ + private String code; + + /** + * 错误码对应的参数 + */ + private Object[] args; + + /** + * 错误消息 + */ + private String defaultMessage; + + public BaseException(String module, String code, Object[] args, String defaultMessage) + { + this.module = module; + this.code = code; + this.args = args; + this.defaultMessage = defaultMessage; + } + + public BaseException(String module, String code, Object[] args) + { + this(module, code, args, null); + } + + public BaseException(String module, String defaultMessage) + { + this(module, null, null, defaultMessage); + } + + public BaseException(String code, Object[] args) + { + this(null, code, args, null); + } + + public BaseException(String defaultMessage) + { + this(null, null, null, defaultMessage); + } + + @Override + public String getMessage() + { + String message = null; + if (!StringUtils.isEmpty(code)) + { + message = MessageUtils.message(code, args); + } + if (message == null) + { + message = defaultMessage; + } + return message; + } + + public String getModule() + { + return module; + } + + public String getCode() + { + return code; + } + + public Object[] getArgs() + { + return args; + } + + public String getDefaultMessage() + { + return defaultMessage; + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/exception/file/FileException.java b/zzyl-common/src/main/java/com/zzyl/common/exception/file/FileException.java new file mode 100644 index 0000000..9ad5cef --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/exception/file/FileException.java @@ -0,0 +1,19 @@ +package com.zzyl.common.exception.file; + +import com.zzyl.common.exception.base.BaseException; + +/** + * 文件信息异常类 + * + * @author ruoyi + */ +public class FileException extends BaseException +{ + private static final long serialVersionUID = 1L; + + public FileException(String code, Object[] args) + { + super("file", code, args, null); + } + +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/exception/file/FileNameLengthLimitExceededException.java b/zzyl-common/src/main/java/com/zzyl/common/exception/file/FileNameLengthLimitExceededException.java new file mode 100644 index 0000000..f01e980 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/exception/file/FileNameLengthLimitExceededException.java @@ -0,0 +1,16 @@ +package com.zzyl.common.exception.file; + +/** + * 文件名称超长限制异常类 + * + * @author ruoyi + */ +public class FileNameLengthLimitExceededException extends FileException +{ + private static final long serialVersionUID = 1L; + + public FileNameLengthLimitExceededException(int defaultFileNameLength) + { + super("upload.filename.exceed.length", new Object[] { defaultFileNameLength }); + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/exception/file/FileSizeLimitExceededException.java b/zzyl-common/src/main/java/com/zzyl/common/exception/file/FileSizeLimitExceededException.java new file mode 100644 index 0000000..d5dc322 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/exception/file/FileSizeLimitExceededException.java @@ -0,0 +1,16 @@ +package com.zzyl.common.exception.file; + +/** + * 文件名大小限制异常类 + * + * @author ruoyi + */ +public class FileSizeLimitExceededException extends FileException +{ + private static final long serialVersionUID = 1L; + + public FileSizeLimitExceededException(long defaultMaxSize) + { + super("upload.exceed.maxSize", new Object[] { defaultMaxSize }); + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/exception/file/FileUploadException.java b/zzyl-common/src/main/java/com/zzyl/common/exception/file/FileUploadException.java new file mode 100644 index 0000000..f4d2fd9 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/exception/file/FileUploadException.java @@ -0,0 +1,61 @@ +package com.zzyl.common.exception.file; + +import java.io.PrintStream; +import java.io.PrintWriter; + +/** + * 文件上传异常类 + * + * @author ruoyi + */ +public class FileUploadException extends Exception +{ + + private static final long serialVersionUID = 1L; + + private final Throwable cause; + + public FileUploadException() + { + this(null, null); + } + + public FileUploadException(final String msg) + { + this(msg, null); + } + + public FileUploadException(String msg, Throwable cause) + { + super(msg); + this.cause = cause; + } + + @Override + public void printStackTrace(PrintStream stream) + { + super.printStackTrace(stream); + if (cause != null) + { + stream.println("Caused by:"); + cause.printStackTrace(stream); + } + } + + @Override + public void printStackTrace(PrintWriter writer) + { + super.printStackTrace(writer); + if (cause != null) + { + writer.println("Caused by:"); + cause.printStackTrace(writer); + } + } + + @Override + public Throwable getCause() + { + return cause; + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/exception/file/InvalidExtensionException.java b/zzyl-common/src/main/java/com/zzyl/common/exception/file/InvalidExtensionException.java new file mode 100644 index 0000000..2bed392 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/exception/file/InvalidExtensionException.java @@ -0,0 +1,80 @@ +package com.zzyl.common.exception.file; + +import java.util.Arrays; + +/** + * 文件上传 误异常类 + * + * @author ruoyi + */ +public class InvalidExtensionException extends FileUploadException +{ + private static final long serialVersionUID = 1L; + + private String[] allowedExtension; + private String extension; + private String filename; + + public InvalidExtensionException(String[] allowedExtension, String extension, String filename) + { + super("文件[" + filename + "]后缀[" + extension + "]不正确,请上传" + Arrays.toString(allowedExtension) + "格式"); + this.allowedExtension = allowedExtension; + this.extension = extension; + this.filename = filename; + } + + public String[] getAllowedExtension() + { + return allowedExtension; + } + + public String getExtension() + { + return extension; + } + + public String getFilename() + { + return filename; + } + + public static class InvalidImageExtensionException extends InvalidExtensionException + { + private static final long serialVersionUID = 1L; + + public InvalidImageExtensionException(String[] allowedExtension, String extension, String filename) + { + super(allowedExtension, extension, filename); + } + } + + public static class InvalidFlashExtensionException extends InvalidExtensionException + { + private static final long serialVersionUID = 1L; + + public InvalidFlashExtensionException(String[] allowedExtension, String extension, String filename) + { + super(allowedExtension, extension, filename); + } + } + + public static class InvalidMediaExtensionException extends InvalidExtensionException + { + private static final long serialVersionUID = 1L; + + public InvalidMediaExtensionException(String[] allowedExtension, String extension, String filename) + { + super(allowedExtension, extension, filename); + } + } + + public static class InvalidVideoExtensionException extends InvalidExtensionException + { + private static final long serialVersionUID = 1L; + + public InvalidVideoExtensionException(String[] allowedExtension, String extension, String filename) + { + super(allowedExtension, extension, filename); + } + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/exception/job/TaskException.java b/zzyl-common/src/main/java/com/zzyl/common/exception/job/TaskException.java new file mode 100644 index 0000000..770236b --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/exception/job/TaskException.java @@ -0,0 +1,34 @@ +package com.zzyl.common.exception.job; + +/** + * 计划策略异常 + * + * @author ruoyi + */ +public class TaskException extends Exception +{ + private static final long serialVersionUID = 1L; + + private Code code; + + public TaskException(String msg, Code code) + { + this(msg, code, null); + } + + public TaskException(String msg, Code code, Exception nestedEx) + { + super(msg, nestedEx); + this.code = code; + } + + public Code getCode() + { + return code; + } + + public enum Code + { + TASK_EXISTS, NO_TASK_EXISTS, TASK_ALREADY_STARTED, UNKNOWN, CONFIG_ERROR, TASK_NODE_NOT_AVAILABLE + } +} \ No newline at end of file diff --git a/zzyl-common/src/main/java/com/zzyl/common/exception/user/BlackListException.java b/zzyl-common/src/main/java/com/zzyl/common/exception/user/BlackListException.java new file mode 100644 index 0000000..4b307de --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/exception/user/BlackListException.java @@ -0,0 +1,16 @@ +package com.zzyl.common.exception.user; + +/** + * 黑名单IP异常类 + * + * @author ruoyi + */ +public class BlackListException extends UserException +{ + private static final long serialVersionUID = 1L; + + public BlackListException() + { + super("login.blocked", null); + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/exception/user/CaptchaException.java b/zzyl-common/src/main/java/com/zzyl/common/exception/user/CaptchaException.java new file mode 100644 index 0000000..c519f01 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/exception/user/CaptchaException.java @@ -0,0 +1,16 @@ +package com.zzyl.common.exception.user; + +/** + * 验证码错误异常类 + * + * @author ruoyi + */ +public class CaptchaException extends UserException +{ + private static final long serialVersionUID = 1L; + + public CaptchaException() + { + super("user.jcaptcha.error", null); + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/exception/user/CaptchaExpireException.java b/zzyl-common/src/main/java/com/zzyl/common/exception/user/CaptchaExpireException.java new file mode 100644 index 0000000..4a81d22 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/exception/user/CaptchaExpireException.java @@ -0,0 +1,16 @@ +package com.zzyl.common.exception.user; + +/** + * 验证码失效异常类 + * + * @author ruoyi + */ +public class CaptchaExpireException extends UserException +{ + private static final long serialVersionUID = 1L; + + public CaptchaExpireException() + { + super("user.jcaptcha.expire", null); + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/exception/user/UserException.java b/zzyl-common/src/main/java/com/zzyl/common/exception/user/UserException.java new file mode 100644 index 0000000..0ddff7a --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/exception/user/UserException.java @@ -0,0 +1,18 @@ +package com.zzyl.common.exception.user; + +import com.zzyl.common.exception.base.BaseException; + +/** + * 用户信息异常类 + * + * @author ruoyi + */ +public class UserException extends BaseException +{ + private static final long serialVersionUID = 1L; + + public UserException(String code, Object[] args) + { + super("user", code, args, null); + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/exception/user/UserNotExistsException.java b/zzyl-common/src/main/java/com/zzyl/common/exception/user/UserNotExistsException.java new file mode 100644 index 0000000..b2f00ca --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/exception/user/UserNotExistsException.java @@ -0,0 +1,16 @@ +package com.zzyl.common.exception.user; + +/** + * 用户不存在异常类 + * + * @author ruoyi + */ +public class UserNotExistsException extends UserException +{ + private static final long serialVersionUID = 1L; + + public UserNotExistsException() + { + super("user.not.exists", null); + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/exception/user/UserPasswordNotMatchException.java b/zzyl-common/src/main/java/com/zzyl/common/exception/user/UserPasswordNotMatchException.java new file mode 100644 index 0000000..964d19a --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/exception/user/UserPasswordNotMatchException.java @@ -0,0 +1,16 @@ +package com.zzyl.common.exception.user; + +/** + * 用户密码不正确或不符合规范异常类 + * + * @author ruoyi + */ +public class UserPasswordNotMatchException extends UserException +{ + private static final long serialVersionUID = 1L; + + public UserPasswordNotMatchException() + { + super("user.password.not.match", null); + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/exception/user/UserPasswordRetryLimitExceedException.java b/zzyl-common/src/main/java/com/zzyl/common/exception/user/UserPasswordRetryLimitExceedException.java new file mode 100644 index 0000000..7358618 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/exception/user/UserPasswordRetryLimitExceedException.java @@ -0,0 +1,16 @@ +package com.zzyl.common.exception.user; + +/** + * 用户错误最大次数异常类 + * + * @author ruoyi + */ +public class UserPasswordRetryLimitExceedException extends UserException +{ + private static final long serialVersionUID = 1L; + + public UserPasswordRetryLimitExceedException(int retryLimitCount, int lockTime) + { + super("user.password.retry.limit.exceed", new Object[] { retryLimitCount, lockTime }); + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/filter/PropertyPreExcludeFilter.java b/zzyl-common/src/main/java/com/zzyl/common/filter/PropertyPreExcludeFilter.java new file mode 100644 index 0000000..e404611 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/filter/PropertyPreExcludeFilter.java @@ -0,0 +1,24 @@ +package com.zzyl.common.filter; + +import com.alibaba.fastjson2.filter.SimplePropertyPreFilter; + +/** + * 排除JSON敏感属性 + * + * @author ruoyi + */ +public class PropertyPreExcludeFilter extends SimplePropertyPreFilter +{ + public PropertyPreExcludeFilter() + { + } + + public PropertyPreExcludeFilter addExcludes(String... filters) + { + for (int i = 0; i < filters.length; i++) + { + this.getExcludes().add(filters[i]); + } + return this; + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/filter/RepeatableFilter.java b/zzyl-common/src/main/java/com/zzyl/common/filter/RepeatableFilter.java new file mode 100644 index 0000000..dcb9886 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/filter/RepeatableFilter.java @@ -0,0 +1,52 @@ +package com.zzyl.common.filter; + +import java.io.IOException; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import org.springframework.http.MediaType; +import com.zzyl.common.utils.StringUtils; + +/** + * Repeatable 过滤器 + * + * @author ruoyi + */ +public class RepeatableFilter implements Filter +{ + @Override + public void init(FilterConfig filterConfig) throws ServletException + { + + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException + { + ServletRequest requestWrapper = null; + if (request instanceof HttpServletRequest + && StringUtils.startsWithIgnoreCase(request.getContentType(), MediaType.APPLICATION_JSON_VALUE)) + { + requestWrapper = new RepeatedlyRequestWrapper((HttpServletRequest) request, response); + } + if (null == requestWrapper) + { + chain.doFilter(request, response); + } + else + { + chain.doFilter(requestWrapper, response); + } + } + + @Override + public void destroy() + { + + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/filter/RepeatedlyRequestWrapper.java b/zzyl-common/src/main/java/com/zzyl/common/filter/RepeatedlyRequestWrapper.java new file mode 100644 index 0000000..f9bc110 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/filter/RepeatedlyRequestWrapper.java @@ -0,0 +1,76 @@ +package com.zzyl.common.filter; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import javax.servlet.ReadListener; +import javax.servlet.ServletInputStream; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import com.zzyl.common.utils.http.HttpHelper; +import com.zzyl.common.constant.Constants; + +/** + * 构建可重复读取inputStream的request + * + * @author ruoyi + */ +public class RepeatedlyRequestWrapper extends HttpServletRequestWrapper +{ + private final byte[] body; + + public RepeatedlyRequestWrapper(HttpServletRequest request, ServletResponse response) throws IOException + { + super(request); + request.setCharacterEncoding(Constants.UTF8); + response.setCharacterEncoding(Constants.UTF8); + + body = HttpHelper.getBodyString(request).getBytes(Constants.UTF8); + } + + @Override + public BufferedReader getReader() throws IOException + { + return new BufferedReader(new InputStreamReader(getInputStream())); + } + + @Override + public ServletInputStream getInputStream() throws IOException + { + final ByteArrayInputStream bais = new ByteArrayInputStream(body); + return new ServletInputStream() + { + @Override + public int read() throws IOException + { + return bais.read(); + } + + @Override + public int available() throws IOException + { + return body.length; + } + + @Override + public boolean isFinished() + { + return false; + } + + @Override + public boolean isReady() + { + return false; + } + + @Override + public void setReadListener(ReadListener readListener) + { + + } + }; + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/filter/XssFilter.java b/zzyl-common/src/main/java/com/zzyl/common/filter/XssFilter.java new file mode 100644 index 0000000..6953e1e --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/filter/XssFilter.java @@ -0,0 +1,75 @@ +package com.zzyl.common.filter; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.common.enums.HttpMethod; + +/** + * 防止XSS攻击的过滤器 + * + * @author ruoyi + */ +public class XssFilter implements Filter +{ + /** + * 排除链接 + */ + public List excludes = new ArrayList<>(); + + @Override + public void init(FilterConfig filterConfig) throws ServletException + { + String tempExcludes = filterConfig.getInitParameter("excludes"); + if (StringUtils.isNotEmpty(tempExcludes)) + { + String[] urls = tempExcludes.split(","); + for (String url : urls) + { + excludes.add(url); + } + } + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException + { + HttpServletRequest req = (HttpServletRequest) request; + HttpServletResponse resp = (HttpServletResponse) response; + if (handleExcludeURL(req, resp)) + { + chain.doFilter(request, response); + return; + } + XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper((HttpServletRequest) request); + chain.doFilter(xssRequest, response); + } + + private boolean handleExcludeURL(HttpServletRequest request, HttpServletResponse response) + { + String url = request.getServletPath(); + String method = request.getMethod(); + // GET DELETE 不过滤 + if (method == null || HttpMethod.GET.matches(method) || HttpMethod.DELETE.matches(method)) + { + return true; + } + return StringUtils.matches(url, excludes); + } + + @Override + public void destroy() + { + + } +} \ No newline at end of file diff --git a/zzyl-common/src/main/java/com/zzyl/common/filter/XssHttpServletRequestWrapper.java b/zzyl-common/src/main/java/com/zzyl/common/filter/XssHttpServletRequestWrapper.java new file mode 100644 index 0000000..c21f833 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/filter/XssHttpServletRequestWrapper.java @@ -0,0 +1,111 @@ +package com.zzyl.common.filter; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import javax.servlet.ReadListener; +import javax.servlet.ServletInputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import org.apache.commons.io.IOUtils; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.common.utils.html.EscapeUtil; + +/** + * XSS过滤处理 + * + * @author ruoyi + */ +public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper +{ + /** + * @param request + */ + public XssHttpServletRequestWrapper(HttpServletRequest request) + { + super(request); + } + + @Override + public String[] getParameterValues(String name) + { + String[] values = super.getParameterValues(name); + if (values != null) + { + int length = values.length; + String[] escapesValues = new String[length]; + for (int i = 0; i < length; i++) + { + // 防xss攻击和过滤前后空格 + escapesValues[i] = EscapeUtil.clean(values[i]).trim(); + } + return escapesValues; + } + return super.getParameterValues(name); + } + + @Override + public ServletInputStream getInputStream() throws IOException + { + // 非json类型,直接返回 + if (!isJsonRequest()) + { + return super.getInputStream(); + } + + // 为空,直接返回 + String json = IOUtils.toString(super.getInputStream(), "utf-8"); + if (StringUtils.isEmpty(json)) + { + return super.getInputStream(); + } + + // xss过滤 + json = EscapeUtil.clean(json).trim(); + byte[] jsonBytes = json.getBytes("utf-8"); + final ByteArrayInputStream bis = new ByteArrayInputStream(jsonBytes); + return new ServletInputStream() + { + @Override + public boolean isFinished() + { + return true; + } + + @Override + public boolean isReady() + { + return true; + } + + @Override + public int available() throws IOException + { + return jsonBytes.length; + } + + @Override + public void setReadListener(ReadListener readListener) + { + } + + @Override + public int read() throws IOException + { + return bis.read(); + } + }; + } + + /** + * 是否是Json请求 + * + * @param request + */ + public boolean isJsonRequest() + { + String header = super.getHeader(HttpHeaders.CONTENT_TYPE); + return StringUtils.startsWithIgnoreCase(header, MediaType.APPLICATION_JSON_VALUE); + } +} \ No newline at end of file diff --git a/zzyl-common/src/main/java/com/zzyl/common/utils/Arith.java b/zzyl-common/src/main/java/com/zzyl/common/utils/Arith.java new file mode 100644 index 0000000..db58782 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/utils/Arith.java @@ -0,0 +1,114 @@ +package com.zzyl.common.utils; + +import java.math.BigDecimal; +import java.math.RoundingMode; + +/** + * 精确的浮点数运算 + * + * @author ruoyi + */ +public class Arith +{ + + /** 默认除法运算精度 */ + private static final int DEF_DIV_SCALE = 10; + + /** 这个类不能实例化 */ + private Arith() + { + } + + /** + * 提供精确的加法运算。 + * @param v1 被加数 + * @param v2 加数 + * @return 两个参数的和 + */ + public static double add(double v1, double v2) + { + BigDecimal b1 = new BigDecimal(Double.toString(v1)); + BigDecimal b2 = new BigDecimal(Double.toString(v2)); + return b1.add(b2).doubleValue(); + } + + /** + * 提供精确的减法运算。 + * @param v1 被减数 + * @param v2 减数 + * @return 两个参数的差 + */ + public static double sub(double v1, double v2) + { + BigDecimal b1 = new BigDecimal(Double.toString(v1)); + BigDecimal b2 = new BigDecimal(Double.toString(v2)); + return b1.subtract(b2).doubleValue(); + } + + /** + * 提供精确的乘法运算。 + * @param v1 被乘数 + * @param v2 乘数 + * @return 两个参数的积 + */ + public static double mul(double v1, double v2) + { + BigDecimal b1 = new BigDecimal(Double.toString(v1)); + BigDecimal b2 = new BigDecimal(Double.toString(v2)); + return b1.multiply(b2).doubleValue(); + } + + /** + * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到 + * 小数点以后10位,以后的数字四舍五入。 + * @param v1 被除数 + * @param v2 除数 + * @return 两个参数的商 + */ + public static double div(double v1, double v2) + { + return div(v1, v2, DEF_DIV_SCALE); + } + + /** + * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 + * 定精度,以后的数字四舍五入。 + * @param v1 被除数 + * @param v2 除数 + * @param scale 表示表示需要精确到小数点以后几位。 + * @return 两个参数的商 + */ + public static double div(double v1, double v2, int scale) + { + if (scale < 0) + { + throw new IllegalArgumentException( + "The scale must be a positive integer or zero"); + } + BigDecimal b1 = new BigDecimal(Double.toString(v1)); + BigDecimal b2 = new BigDecimal(Double.toString(v2)); + if (b1.compareTo(BigDecimal.ZERO) == 0) + { + return BigDecimal.ZERO.doubleValue(); + } + return b1.divide(b2, scale, RoundingMode.HALF_UP).doubleValue(); + } + + /** + * 提供精确的小数位四舍五入处理。 + * @param v 需要四舍五入的数字 + * @param scale 小数点后保留几位 + * @return 四舍五入后的结果 + */ + public static double round(double v, int scale) + { + if (scale < 0) + { + throw new IllegalArgumentException( + "The scale must be a positive integer or zero"); + } + BigDecimal b = new BigDecimal(Double.toString(v)); + BigDecimal one = BigDecimal.ONE; + return b.divide(one, scale, RoundingMode.HALF_UP).doubleValue(); + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/utils/DateUtils.java b/zzyl-common/src/main/java/com/zzyl/common/utils/DateUtils.java new file mode 100644 index 0000000..b41460b --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/utils/DateUtils.java @@ -0,0 +1,191 @@ +package com.zzyl.common.utils; + +import java.lang.management.ManagementFactory; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.util.Date; +import org.apache.commons.lang3.time.DateFormatUtils; + +/** + * 时间工具类 + * + * @author ruoyi + */ +public class DateUtils extends org.apache.commons.lang3.time.DateUtils +{ + public static String YYYY = "yyyy"; + + public static String YYYY_MM = "yyyy-MM"; + + public static String YYYY_MM_DD = "yyyy-MM-dd"; + + public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss"; + + public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss"; + + private static String[] parsePatterns = { + "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM", + "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM", + "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"}; + + /** + * 获取当前Date型日期 + * + * @return Date() 当前日期 + */ + public static Date getNowDate() + { + return new Date(); + } + + /** + * 获取当前日期, 默认格式为yyyy-MM-dd + * + * @return String + */ + public static String getDate() + { + return dateTimeNow(YYYY_MM_DD); + } + + public static final String getTime() + { + return dateTimeNow(YYYY_MM_DD_HH_MM_SS); + } + + public static final String dateTimeNow() + { + return dateTimeNow(YYYYMMDDHHMMSS); + } + + public static final String dateTimeNow(final String format) + { + return parseDateToStr(format, new Date()); + } + + public static final String dateTime(final Date date) + { + return parseDateToStr(YYYY_MM_DD, date); + } + + public static final String parseDateToStr(final String format, final Date date) + { + return new SimpleDateFormat(format).format(date); + } + + public static final Date dateTime(final String format, final String ts) + { + try + { + return new SimpleDateFormat(format).parse(ts); + } + catch (ParseException e) + { + throw new RuntimeException(e); + } + } + + /** + * 日期路径 即年/月/日 如2018/08/08 + */ + public static final String datePath() + { + Date now = new Date(); + return DateFormatUtils.format(now, "yyyy/MM/dd"); + } + + /** + * 日期路径 即年/月/日 如20180808 + */ + public static final String dateTime() + { + Date now = new Date(); + return DateFormatUtils.format(now, "yyyyMMdd"); + } + + /** + * 日期型字符串转化为日期 格式 + */ + public static Date parseDate(Object str) + { + if (str == null) + { + return null; + } + try + { + return parseDate(str.toString(), parsePatterns); + } + catch (ParseException e) + { + return null; + } + } + + /** + * 获取服务器启动时间 + */ + public static Date getServerStartDate() + { + long time = ManagementFactory.getRuntimeMXBean().getStartTime(); + return new Date(time); + } + + /** + * 计算相差天数 + */ + public static int differentDaysByMillisecond(Date date1, Date date2) + { + return Math.abs((int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24))); + } + + /** + * 计算时间差 + * + * @param endDate 最后时间 + * @param startTime 开始时间 + * @return 时间差(天/小时/分钟) + */ + public static String timeDistance(Date endDate, Date startTime) + { + long nd = 1000 * 24 * 60 * 60; + long nh = 1000 * 60 * 60; + long nm = 1000 * 60; + // long ns = 1000; + // 获得两个时间的毫秒时间差异 + long diff = endDate.getTime() - startTime.getTime(); + // 计算差多少天 + long day = diff / nd; + // 计算差多少小时 + long hour = diff % nd / nh; + // 计算差多少分钟 + long min = diff % nd % nh / nm; + // 计算差多少秒//输出结果 + // long sec = diff % nd % nh % nm / ns; + return day + "天" + hour + "小时" + min + "分钟"; + } + + /** + * 增加 LocalDateTime ==> Date + */ + public static Date toDate(LocalDateTime temporalAccessor) + { + ZonedDateTime zdt = temporalAccessor.atZone(ZoneId.systemDefault()); + return Date.from(zdt.toInstant()); + } + + /** + * 增加 LocalDate ==> Date + */ + public static Date toDate(LocalDate temporalAccessor) + { + LocalDateTime localDateTime = LocalDateTime.of(temporalAccessor, LocalTime.of(0, 0, 0)); + ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault()); + return Date.from(zdt.toInstant()); + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/utils/DesensitizedUtil.java b/zzyl-common/src/main/java/com/zzyl/common/utils/DesensitizedUtil.java new file mode 100644 index 0000000..a9cf9af --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/utils/DesensitizedUtil.java @@ -0,0 +1,49 @@ +package com.zzyl.common.utils; + +/** + * 脱敏工具类 + * + * @author ruoyi + */ +public class DesensitizedUtil +{ + /** + * 密码的全部字符都用*代替,比如:****** + * + * @param password 密码 + * @return 脱敏后的密码 + */ + public static String password(String password) + { + if (StringUtils.isBlank(password)) + { + return StringUtils.EMPTY; + } + return StringUtils.repeat('*', password.length()); + } + + /** + * 车牌中间用*代替,如果是错误的车牌,不处理 + * + * @param carLicense 完整的车牌号 + * @return 脱敏后的车牌 + */ + public static String carLicense(String carLicense) + { + if (StringUtils.isBlank(carLicense)) + { + return StringUtils.EMPTY; + } + // 普通车牌 + if (carLicense.length() == 7) + { + carLicense = StringUtils.hide(carLicense, 3, 6); + } + else if (carLicense.length() == 8) + { + // 新能源车牌 + carLicense = StringUtils.hide(carLicense, 3, 7); + } + return carLicense; + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/utils/DictUtils.java b/zzyl-common/src/main/java/com/zzyl/common/utils/DictUtils.java new file mode 100644 index 0000000..a7c89fd --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/utils/DictUtils.java @@ -0,0 +1,239 @@ +package com.zzyl.common.utils; + +import java.util.Collection; +import java.util.List; +import com.alibaba.fastjson2.JSONArray; +import com.zzyl.common.constant.CacheConstants; +import com.zzyl.common.core.domain.entity.SysDictData; +import com.zzyl.common.core.redis.RedisCache; +import com.zzyl.common.utils.spring.SpringUtils; + +/** + * 字典工具类 + * + * @author ruoyi + */ +public class DictUtils +{ + /** + * 分隔符 + */ + public static final String SEPARATOR = ","; + + /** + * 设置字典缓存 + * + * @param key 参数键 + * @param dictDatas 字典数据列表 + */ + public static void setDictCache(String key, List dictDatas) + { + SpringUtils.getBean(RedisCache.class).setCacheObject(getCacheKey(key), dictDatas); + } + + /** + * 获取字典缓存 + * + * @param key 参数键 + * @return dictDatas 字典数据列表 + */ + public static List getDictCache(String key) + { + JSONArray arrayCache = SpringUtils.getBean(RedisCache.class).getCacheObject(getCacheKey(key)); + if (StringUtils.isNotNull(arrayCache)) + { + return arrayCache.toList(SysDictData.class); + } + return null; + } + + /** + * 根据字典类型和字典值获取字典标签 + * + * @param dictType 字典类型 + * @param dictValue 字典值 + * @return 字典标签 + */ + public static String getDictLabel(String dictType, String dictValue) + { + if (StringUtils.isEmpty(dictValue)) + { + return StringUtils.EMPTY; + } + return getDictLabel(dictType, dictValue, SEPARATOR); + } + + /** + * 根据字典类型和字典标签获取字典值 + * + * @param dictType 字典类型 + * @param dictLabel 字典标签 + * @return 字典值 + */ + public static String getDictValue(String dictType, String dictLabel) + { + if (StringUtils.isEmpty(dictLabel)) + { + return StringUtils.EMPTY; + } + return getDictValue(dictType, dictLabel, SEPARATOR); + } + + /** + * 根据字典类型和字典值获取字典标签 + * + * @param dictType 字典类型 + * @param dictValue 字典值 + * @param separator 分隔符 + * @return 字典标签 + */ + public static String getDictLabel(String dictType, String dictValue, String separator) + { + StringBuilder propertyString = new StringBuilder(); + List datas = getDictCache(dictType); + if (StringUtils.isNull(datas)) + { + return StringUtils.EMPTY; + } + if (StringUtils.containsAny(separator, dictValue)) + { + for (SysDictData dict : datas) + { + for (String value : dictValue.split(separator)) + { + if (value.equals(dict.getDictValue())) + { + propertyString.append(dict.getDictLabel()).append(separator); + break; + } + } + } + } + else + { + for (SysDictData dict : datas) + { + if (dictValue.equals(dict.getDictValue())) + { + return dict.getDictLabel(); + } + } + } + return StringUtils.stripEnd(propertyString.toString(), separator); + } + + /** + * 根据字典类型和字典标签获取字典值 + * + * @param dictType 字典类型 + * @param dictLabel 字典标签 + * @param separator 分隔符 + * @return 字典值 + */ + public static String getDictValue(String dictType, String dictLabel, String separator) + { + StringBuilder propertyString = new StringBuilder(); + List datas = getDictCache(dictType); + if (StringUtils.isNull(datas)) + { + return StringUtils.EMPTY; + } + if (StringUtils.containsAny(separator, dictLabel)) + { + for (SysDictData dict : datas) + { + for (String label : dictLabel.split(separator)) + { + if (label.equals(dict.getDictLabel())) + { + propertyString.append(dict.getDictValue()).append(separator); + break; + } + } + } + } + else + { + for (SysDictData dict : datas) + { + if (dictLabel.equals(dict.getDictLabel())) + { + return dict.getDictValue(); + } + } + } + return StringUtils.stripEnd(propertyString.toString(), separator); + } + + /** + * 根据字典类型获取字典所有值 + * + * @param dictType 字典类型 + * @return 字典值 + */ + public static String getDictValues(String dictType) + { + StringBuilder propertyString = new StringBuilder(); + List datas = getDictCache(dictType); + if (StringUtils.isNull(datas)) + { + return StringUtils.EMPTY; + } + for (SysDictData dict : datas) + { + propertyString.append(dict.getDictValue()).append(SEPARATOR); + } + return StringUtils.stripEnd(propertyString.toString(), SEPARATOR); + } + + /** + * 根据字典类型获取字典所有标签 + * + * @param dictType 字典类型 + * @return 字典值 + */ + public static String getDictLabels(String dictType) + { + StringBuilder propertyString = new StringBuilder(); + List datas = getDictCache(dictType); + if (StringUtils.isNull(datas)) + { + return StringUtils.EMPTY; + } + for (SysDictData dict : datas) + { + propertyString.append(dict.getDictLabel()).append(SEPARATOR); + } + return StringUtils.stripEnd(propertyString.toString(), SEPARATOR); + } + + /** + * 删除指定字典缓存 + * + * @param key 字典键 + */ + public static void removeDictCache(String key) + { + SpringUtils.getBean(RedisCache.class).deleteObject(getCacheKey(key)); + } + + /** + * 清空字典缓存 + */ + public static void clearDictCache() + { + Collection keys = SpringUtils.getBean(RedisCache.class).keys(CacheConstants.SYS_DICT_KEY + "*"); + SpringUtils.getBean(RedisCache.class).deleteObject(keys); + } + + /** + * 设置cache key + * + * @param configKey 参数键 + * @return 缓存键key + */ + public static String getCacheKey(String configKey) + { + return CacheConstants.SYS_DICT_KEY + configKey; + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/utils/ExceptionUtil.java b/zzyl-common/src/main/java/com/zzyl/common/utils/ExceptionUtil.java new file mode 100644 index 0000000..6589436 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/utils/ExceptionUtil.java @@ -0,0 +1,39 @@ +package com.zzyl.common.utils; + +import java.io.PrintWriter; +import java.io.StringWriter; +import org.apache.commons.lang3.exception.ExceptionUtils; + +/** + * 错误信息处理类。 + * + * @author ruoyi + */ +public class ExceptionUtil +{ + /** + * 获取exception的详细错误信息。 + */ + public static String getExceptionMessage(Throwable e) + { + StringWriter sw = new StringWriter(); + e.printStackTrace(new PrintWriter(sw, true)); + return sw.toString(); + } + + public static String getRootErrorMessage(Exception e) + { + Throwable root = ExceptionUtils.getRootCause(e); + root = (root == null ? e : root); + if (root == null) + { + return ""; + } + String msg = root.getMessage(); + if (msg == null) + { + return "null"; + } + return StringUtils.defaultString(msg); + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/utils/LogUtils.java b/zzyl-common/src/main/java/com/zzyl/common/utils/LogUtils.java new file mode 100644 index 0000000..ccef184 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/utils/LogUtils.java @@ -0,0 +1,18 @@ +package com.zzyl.common.utils; + +/** + * 处理并记录日志文件 + * + * @author ruoyi + */ +public class LogUtils +{ + public static String getBlock(Object msg) + { + if (msg == null) + { + msg = ""; + } + return "[" + msg.toString() + "]"; + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/utils/MessageUtils.java b/zzyl-common/src/main/java/com/zzyl/common/utils/MessageUtils.java new file mode 100644 index 0000000..455d890 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/utils/MessageUtils.java @@ -0,0 +1,26 @@ +package com.zzyl.common.utils; + +import org.springframework.context.MessageSource; +import org.springframework.context.i18n.LocaleContextHolder; +import com.zzyl.common.utils.spring.SpringUtils; + +/** + * 获取i18n资源文件 + * + * @author ruoyi + */ +public class MessageUtils +{ + /** + * 根据消息键和参数 获取消息 委托给spring messageSource + * + * @param code 消息键 + * @param args 参数 + * @return 获取国际化翻译值 + */ + public static String message(String code, Object... args) + { + MessageSource messageSource = SpringUtils.getBean(MessageSource.class); + return messageSource.getMessage(code, args, LocaleContextHolder.getLocale()); + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/utils/PDFUtil.java b/zzyl-common/src/main/java/com/zzyl/common/utils/PDFUtil.java new file mode 100644 index 0000000..d5302cd --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/utils/PDFUtil.java @@ -0,0 +1,49 @@ +package com.zzyl.common.utils; + +import lombok.extern.slf4j.Slf4j; +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.text.PDFTextStripper; + +import java.io.IOException; +import java.io.InputStream; + +/** + * PDF工具类 + * + * @Author: Zhy + * @Date: 2025-02-28 12:04 + * @Version: 1.0 + */ +@Slf4j +public class PDFUtil { + + public static String pdfToString(InputStream inputStream) { + + PDDocument document = null; + + try { + // 加载PDF文档 + document = PDDocument.load(inputStream); + + // 创建一个PDFTextStripper实例来提取文本 + PDFTextStripper pdfStripper = new PDFTextStripper(); + + // 从PDF文档中提取文本 + return pdfStripper.getText(document); + + } catch (IOException e) { + log.error("PDF转字符串异常:", e); + } finally { + // 关闭PDF文档 + if (document != null) { + try { + document.close(); + inputStream.close(); + } catch (IOException e) { + log.error("关闭PDF文档异常:", e); + } + } + } + return null; + } +} \ No newline at end of file diff --git a/zzyl-common/src/main/java/com/zzyl/common/utils/PageUtils.java b/zzyl-common/src/main/java/com/zzyl/common/utils/PageUtils.java new file mode 100644 index 0000000..98df9e1 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/utils/PageUtils.java @@ -0,0 +1,35 @@ +package com.zzyl.common.utils; + +import com.github.pagehelper.PageHelper; +import com.zzyl.common.core.page.PageDomain; +import com.zzyl.common.core.page.TableSupport; +import com.zzyl.common.utils.sql.SqlUtil; + +/** + * 分页工具类 + * + * @author ruoyi + */ +public class PageUtils extends PageHelper +{ + /** + * 设置请求分页数据 + */ + public static void startPage() + { + PageDomain pageDomain = TableSupport.buildPageRequest(); + Integer pageNum = pageDomain.getPageNum(); + Integer pageSize = pageDomain.getPageSize(); + String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy()); + Boolean reasonable = pageDomain.getReasonable(); + PageHelper.startPage(pageNum, pageSize, orderBy).setReasonable(reasonable); + } + + /** + * 清理分页的线程变量 + */ + public static void clearPage() + { + PageHelper.clearPage(); + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/utils/SecurityUtils.java b/zzyl-common/src/main/java/com/zzyl/common/utils/SecurityUtils.java new file mode 100644 index 0000000..f5b07fb --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/utils/SecurityUtils.java @@ -0,0 +1,178 @@ +package com.zzyl.common.utils; + +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.util.PatternMatchUtils; +import com.zzyl.common.constant.Constants; +import com.zzyl.common.constant.HttpStatus; +import com.zzyl.common.core.domain.entity.SysRole; +import com.zzyl.common.core.domain.model.LoginUser; +import com.zzyl.common.exception.ServiceException; + +/** + * 安全服务工具类 + * + * @author ruoyi + */ +public class SecurityUtils +{ + + /** + * 用户ID + **/ + public static Long getUserId() + { + try + { + return getLoginUser().getUserId(); + } + catch (Exception e) + { + throw new ServiceException("获取用户ID异常", HttpStatus.UNAUTHORIZED); + } + } + + /** + * 获取部门ID + **/ + public static Long getDeptId() + { + try + { + return getLoginUser().getDeptId(); + } + catch (Exception e) + { + throw new ServiceException("获取部门ID异常", HttpStatus.UNAUTHORIZED); + } + } + + /** + * 获取用户账户 + **/ + public static String getUsername() + { + try + { + return getLoginUser().getUsername(); + } + catch (Exception e) + { + throw new ServiceException("获取用户账户异常", HttpStatus.UNAUTHORIZED); + } + } + + /** + * 获取用户 + **/ + public static LoginUser getLoginUser() + { + try + { + return (LoginUser) getAuthentication().getPrincipal(); + } + catch (Exception e) + { + throw new ServiceException("获取用户信息异常", HttpStatus.UNAUTHORIZED); + } + } + + /** + * 获取Authentication + */ + public static Authentication getAuthentication() + { + return SecurityContextHolder.getContext().getAuthentication(); + } + + /** + * 生成BCryptPasswordEncoder密码 + * + * @param password 密码 + * @return 加密字符串 + */ + public static String encryptPassword(String password) + { + BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); + return passwordEncoder.encode(password); + } + + /** + * 判断密码是否相同 + * + * @param rawPassword 真实密码 + * @param encodedPassword 加密后字符 + * @return 结果 + */ + public static boolean matchesPassword(String rawPassword, String encodedPassword) + { + BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); + return passwordEncoder.matches(rawPassword, encodedPassword); + } + + /** + * 是否为管理员 + * + * @param userId 用户ID + * @return 结果 + */ + public static boolean isAdmin(Long userId) + { + return userId != null && 1L == userId; + } + + /** + * 验证用户是否具备某权限 + * + * @param permission 权限字符串 + * @return 用户是否具备某权限 + */ + public static boolean hasPermi(String permission) + { + return hasPermi(getLoginUser().getPermissions(), permission); + } + + /** + * 判断是否包含权限 + * + * @param authorities 权限列表 + * @param permission 权限字符串 + * @return 用户是否具备某权限 + */ + public static boolean hasPermi(Collection authorities, String permission) + { + return authorities.stream().filter(StringUtils::hasText) + .anyMatch(x -> Constants.ALL_PERMISSION.equals(x) || PatternMatchUtils.simpleMatch(x, permission)); + } + + /** + * 验证用户是否拥有某个角色 + * + * @param role 角色标识 + * @return 用户是否具备某角色 + */ + public static boolean hasRole(String role) + { + List roleList = getLoginUser().getUser().getRoles(); + Collection roles = roleList.stream().map(SysRole::getRoleKey).collect(Collectors.toSet()); + return hasRole(roles, role); + } + + /** + * 判断是否包含角色 + * + * @param roles 角色列表 + * @param role 角色 + * @return 用户是否具备某角色权限 + */ + public static boolean hasRole(Collection roles, String role) + { + return roles.stream().filter(StringUtils::hasText) + .anyMatch(x -> Constants.SUPER_ADMIN.equals(x) || PatternMatchUtils.simpleMatch(x, role)); + } + +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/utils/ServletUtils.java b/zzyl-common/src/main/java/com/zzyl/common/utils/ServletUtils.java new file mode 100644 index 0000000..53853b4 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/utils/ServletUtils.java @@ -0,0 +1,218 @@ +package com.zzyl.common.utils; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import javax.servlet.ServletRequest; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; +import com.zzyl.common.constant.Constants; +import com.zzyl.common.core.text.Convert; + +/** + * 客户端工具类 + * + * @author ruoyi + */ +public class ServletUtils +{ + /** + * 获取String参数 + */ + public static String getParameter(String name) + { + return getRequest().getParameter(name); + } + + /** + * 获取String参数 + */ + public static String getParameter(String name, String defaultValue) + { + return Convert.toStr(getRequest().getParameter(name), defaultValue); + } + + /** + * 获取Integer参数 + */ + public static Integer getParameterToInt(String name) + { + return Convert.toInt(getRequest().getParameter(name)); + } + + /** + * 获取Integer参数 + */ + public static Integer getParameterToInt(String name, Integer defaultValue) + { + return Convert.toInt(getRequest().getParameter(name), defaultValue); + } + + /** + * 获取Boolean参数 + */ + public static Boolean getParameterToBool(String name) + { + return Convert.toBool(getRequest().getParameter(name)); + } + + /** + * 获取Boolean参数 + */ + public static Boolean getParameterToBool(String name, Boolean defaultValue) + { + return Convert.toBool(getRequest().getParameter(name), defaultValue); + } + + /** + * 获得所有请求参数 + * + * @param request 请求对象{@link ServletRequest} + * @return Map + */ + public static Map getParams(ServletRequest request) + { + final Map map = request.getParameterMap(); + return Collections.unmodifiableMap(map); + } + + /** + * 获得所有请求参数 + * + * @param request 请求对象{@link ServletRequest} + * @return Map + */ + public static Map getParamMap(ServletRequest request) + { + Map params = new HashMap<>(); + for (Map.Entry entry : getParams(request).entrySet()) + { + params.put(entry.getKey(), StringUtils.join(entry.getValue(), ",")); + } + return params; + } + + /** + * 获取request + */ + public static HttpServletRequest getRequest() + { + return getRequestAttributes().getRequest(); + } + + /** + * 获取response + */ + public static HttpServletResponse getResponse() + { + return getRequestAttributes().getResponse(); + } + + /** + * 获取session + */ + public static HttpSession getSession() + { + return getRequest().getSession(); + } + + public static ServletRequestAttributes getRequestAttributes() + { + RequestAttributes attributes = RequestContextHolder.getRequestAttributes(); + return (ServletRequestAttributes) attributes; + } + + /** + * 将字符串渲染到客户端 + * + * @param response 渲染对象 + * @param string 待渲染的字符串 + */ + public static void renderString(HttpServletResponse response, String string) + { + try + { + response.setStatus(200); + response.setContentType("application/json"); + response.setCharacterEncoding("utf-8"); + response.getWriter().print(string); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + + /** + * 是否是Ajax异步请求 + * + * @param request + */ + public static boolean isAjaxRequest(HttpServletRequest request) + { + String accept = request.getHeader("accept"); + if (accept != null && accept.contains("application/json")) + { + return true; + } + + String xRequestedWith = request.getHeader("X-Requested-With"); + if (xRequestedWith != null && xRequestedWith.contains("XMLHttpRequest")) + { + return true; + } + + String uri = request.getRequestURI(); + if (StringUtils.inStringIgnoreCase(uri, ".json", ".xml")) + { + return true; + } + + String ajax = request.getParameter("__ajax"); + return StringUtils.inStringIgnoreCase(ajax, "json", "xml"); + } + + /** + * 内容编码 + * + * @param str 内容 + * @return 编码后的内容 + */ + public static String urlEncode(String str) + { + try + { + return URLEncoder.encode(str, Constants.UTF8); + } + catch (UnsupportedEncodingException e) + { + return StringUtils.EMPTY; + } + } + + /** + * 内容解码 + * + * @param str 内容 + * @return 解码后的内容 + */ + public static String urlDecode(String str) + { + try + { + return URLDecoder.decode(str, Constants.UTF8); + } + catch (UnsupportedEncodingException e) + { + return StringUtils.EMPTY; + } + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/utils/StringUtils.java b/zzyl-common/src/main/java/com/zzyl/common/utils/StringUtils.java new file mode 100644 index 0000000..0f2554c --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/utils/StringUtils.java @@ -0,0 +1,684 @@ +package com.zzyl.common.utils; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import org.springframework.util.AntPathMatcher; +import com.zzyl.common.constant.Constants; +import com.zzyl.common.core.text.StrFormatter; + +/** + * 字符串工具类 + * + * @author ruoyi + */ +public class StringUtils extends org.apache.commons.lang3.StringUtils +{ + /** 空字符串 */ + private static final String NULLSTR = ""; + + /** 下划线 */ + private static final char SEPARATOR = '_'; + + /** 星号 */ + private static final char ASTERISK = '*'; + + /** + * 获取参数不为空值 + * + * @param value defaultValue 要判断的value + * @return value 返回值 + */ + public static T nvl(T value, T defaultValue) + { + return value != null ? value : defaultValue; + } + + /** + * * 判断一个Collection是否为空, 包含List,Set,Queue + * + * @param coll 要判断的Collection + * @return true:为空 false:非空 + */ + public static boolean isEmpty(Collection coll) + { + return isNull(coll) || coll.isEmpty(); + } + + /** + * * 判断一个Collection是否非空,包含List,Set,Queue + * + * @param coll 要判断的Collection + * @return true:非空 false:空 + */ + public static boolean isNotEmpty(Collection coll) + { + return !isEmpty(coll); + } + + /** + * * 判断一个对象数组是否为空 + * + * @param objects 要判断的对象数组 + ** @return true:为空 false:非空 + */ + public static boolean isEmpty(Object[] objects) + { + return isNull(objects) || (objects.length == 0); + } + + /** + * * 判断一个对象数组是否非空 + * + * @param objects 要判断的对象数组 + * @return true:非空 false:空 + */ + public static boolean isNotEmpty(Object[] objects) + { + return !isEmpty(objects); + } + + /** + * * 判断一个Map是否为空 + * + * @param map 要判断的Map + * @return true:为空 false:非空 + */ + public static boolean isEmpty(Map map) + { + return isNull(map) || map.isEmpty(); + } + + /** + * * 判断一个Map是否为空 + * + * @param map 要判断的Map + * @return true:非空 false:空 + */ + public static boolean isNotEmpty(Map map) + { + return !isEmpty(map); + } + + /** + * * 判断一个字符串是否为空串 + * + * @param str String + * @return true:为空 false:非空 + */ + public static boolean isEmpty(String str) + { + return isNull(str) || NULLSTR.equals(str.trim()); + } + + /** + * * 判断一个字符串是否为非空串 + * + * @param str String + * @return true:非空串 false:空串 + */ + public static boolean isNotEmpty(String str) + { + return !isEmpty(str); + } + + /** + * * 判断一个对象是否为空 + * + * @param object Object + * @return true:为空 false:非空 + */ + public static boolean isNull(Object object) + { + return object == null; + } + + /** + * * 判断一个对象是否非空 + * + * @param object Object + * @return true:非空 false:空 + */ + public static boolean isNotNull(Object object) + { + return !isNull(object); + } + + /** + * * 判断一个对象是否是数组类型(Java基本型别的数组) + * + * @param object 对象 + * @return true:是数组 false:不是数组 + */ + public static boolean isArray(Object object) + { + return isNotNull(object) && object.getClass().isArray(); + } + + /** + * 去空格 + */ + public static String trim(String str) + { + return (str == null ? "" : str.trim()); + } + + /** + * 替换指定字符串的指定区间内字符为"*" + * + * @param str 字符串 + * @param startInclude 开始位置(包含) + * @param endExclude 结束位置(不包含) + * @return 替换后的字符串 + */ + public static String hide(CharSequence str, int startInclude, int endExclude) + { + if (isEmpty(str)) + { + return NULLSTR; + } + final int strLength = str.length(); + if (startInclude > strLength) + { + return NULLSTR; + } + if (endExclude > strLength) + { + endExclude = strLength; + } + if (startInclude > endExclude) + { + // 如果起始位置大于结束位置,不替换 + return NULLSTR; + } + final char[] chars = new char[strLength]; + for (int i = 0; i < strLength; i++) + { + if (i >= startInclude && i < endExclude) + { + chars[i] = ASTERISK; + } + else + { + chars[i] = str.charAt(i); + } + } + return new String(chars); + } + + /** + * 截取字符串 + * + * @param str 字符串 + * @param start 开始 + * @return 结果 + */ + public static String substring(final String str, int start) + { + if (str == null) + { + return NULLSTR; + } + + if (start < 0) + { + start = str.length() + start; + } + + if (start < 0) + { + start = 0; + } + if (start > str.length()) + { + return NULLSTR; + } + + return str.substring(start); + } + + /** + * 截取字符串 + * + * @param str 字符串 + * @param start 开始 + * @param end 结束 + * @return 结果 + */ + public static String substring(final String str, int start, int end) + { + if (str == null) + { + return NULLSTR; + } + + if (end < 0) + { + end = str.length() + end; + } + if (start < 0) + { + start = str.length() + start; + } + + if (end > str.length()) + { + end = str.length(); + } + + if (start > end) + { + return NULLSTR; + } + + if (start < 0) + { + start = 0; + } + if (end < 0) + { + end = 0; + } + + return str.substring(start, end); + } + + /** + * 判断是否为空,并且不是空白字符 + * + * @param str 要判断的value + * @return 结果 + */ + public static boolean hasText(String str) + { + return (str != null && !str.isEmpty() && containsText(str)); + } + + private static boolean containsText(CharSequence str) + { + int strLen = str.length(); + for (int i = 0; i < strLen; i++) + { + if (!Character.isWhitespace(str.charAt(i))) + { + return true; + } + } + return false; + } + + /** + * 格式化文本, {} 表示占位符
+ * 此方法只是简单将占位符 {} 按照顺序替换为参数
+ * 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可
+ * 例:
+ * 通常使用:format("this is {} for {}", "a", "b") -> this is a for b
+ * 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a
+ * 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b
+ * + * @param template 文本模板,被替换的部分用 {} 表示 + * @param params 参数值 + * @return 格式化后的文本 + */ + public static String format(String template, Object... params) + { + if (isEmpty(params) || isEmpty(template)) + { + return template; + } + return StrFormatter.format(template, params); + } + + /** + * 是否为http(s)://开头 + * + * @param link 链接 + * @return 结果 + */ + public static boolean ishttp(String link) + { + return StringUtils.startsWithAny(link, Constants.HTTP, Constants.HTTPS); + } + + /** + * 字符串转set + * + * @param str 字符串 + * @param sep 分隔符 + * @return set集合 + */ + public static final Set str2Set(String str, String sep) + { + return new HashSet(str2List(str, sep, true, false)); + } + + /** + * 字符串转list + * + * @param str 字符串 + * @param sep 分隔符 + * @param filterBlank 过滤纯空白 + * @param trim 去掉首尾空白 + * @return list集合 + */ + public static final List str2List(String str, String sep, boolean filterBlank, boolean trim) + { + List list = new ArrayList(); + if (StringUtils.isEmpty(str)) + { + return list; + } + + // 过滤空白字符串 + if (filterBlank && StringUtils.isBlank(str)) + { + return list; + } + String[] split = str.split(sep); + for (String string : split) + { + if (filterBlank && StringUtils.isBlank(string)) + { + continue; + } + if (trim) + { + string = string.trim(); + } + list.add(string); + } + + return list; + } + + /** + * 判断给定的collection列表中是否包含数组array 判断给定的数组array中是否包含给定的元素value + * + * @param collection 给定的集合 + * @param array 给定的数组 + * @return boolean 结果 + */ + public static boolean containsAny(Collection collection, String... array) + { + if (isEmpty(collection) || isEmpty(array)) + { + return false; + } + else + { + for (String str : array) + { + if (collection.contains(str)) + { + return true; + } + } + return false; + } + } + + /** + * 查找指定字符串是否包含指定字符串列表中的任意一个字符串同时串忽略大小写 + * + * @param cs 指定字符串 + * @param searchCharSequences 需要检查的字符串数组 + * @return 是否包含任意一个字符串 + */ + public static boolean containsAnyIgnoreCase(CharSequence cs, CharSequence... searchCharSequences) + { + if (isEmpty(cs) || isEmpty(searchCharSequences)) + { + return false; + } + for (CharSequence testStr : searchCharSequences) + { + if (containsIgnoreCase(cs, testStr)) + { + return true; + } + } + return false; + } + + /** + * 驼峰转下划线命名 + */ + public static String toUnderScoreCase(String str) + { + if (str == null) + { + return null; + } + StringBuilder sb = new StringBuilder(); + // 前置字符是否大写 + boolean preCharIsUpperCase = true; + // 当前字符是否大写 + boolean curreCharIsUpperCase = true; + // 下一字符是否大写 + boolean nexteCharIsUpperCase = true; + for (int i = 0; i < str.length(); i++) + { + char c = str.charAt(i); + if (i > 0) + { + preCharIsUpperCase = Character.isUpperCase(str.charAt(i - 1)); + } + else + { + preCharIsUpperCase = false; + } + + curreCharIsUpperCase = Character.isUpperCase(c); + + if (i < (str.length() - 1)) + { + nexteCharIsUpperCase = Character.isUpperCase(str.charAt(i + 1)); + } + + if (preCharIsUpperCase && curreCharIsUpperCase && !nexteCharIsUpperCase) + { + sb.append(SEPARATOR); + } + else if ((i != 0 && !preCharIsUpperCase) && curreCharIsUpperCase) + { + sb.append(SEPARATOR); + } + sb.append(Character.toLowerCase(c)); + } + + return sb.toString(); + } + + /** + * 是否包含字符串 + * + * @param str 验证字符串 + * @param strs 字符串组 + * @return 包含返回true + */ + public static boolean inStringIgnoreCase(String str, String... strs) + { + if (str != null && strs != null) + { + for (String s : strs) + { + if (str.equalsIgnoreCase(trim(s))) + { + return true; + } + } + } + return false; + } + + /** + * 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。 例如:HELLO_WORLD->HelloWorld + * + * @param name 转换前的下划线大写方式命名的字符串 + * @return 转换后的驼峰式命名的字符串 + */ + public static String convertToCamelCase(String name) + { + StringBuilder result = new StringBuilder(); + // 快速检查 + if (name == null || name.isEmpty()) + { + // 没必要转换 + return ""; + } + else if (!name.contains("_")) + { + // 不含下划线,仅将首字母大写 + return name.substring(0, 1).toUpperCase() + name.substring(1); + } + // 用下划线将原始字符串分割 + String[] camels = name.split("_"); + for (String camel : camels) + { + // 跳过原始字符串中开头、结尾的下换线或双重下划线 + if (camel.isEmpty()) + { + continue; + } + // 首字母大写 + result.append(camel.substring(0, 1).toUpperCase()); + result.append(camel.substring(1).toLowerCase()); + } + return result.toString(); + } + + /** + * 驼峰式命名法 + * 例如:user_name->userName + */ + public static String toCamelCase(String s) + { + if (s == null) + { + return null; + } + if (s.indexOf(SEPARATOR) == -1) + { + return s; + } + s = s.toLowerCase(); + StringBuilder sb = new StringBuilder(s.length()); + boolean upperCase = false; + for (int i = 0; i < s.length(); i++) + { + char c = s.charAt(i); + + if (c == SEPARATOR) + { + upperCase = true; + } + else if (upperCase) + { + sb.append(Character.toUpperCase(c)); + upperCase = false; + } + else + { + sb.append(c); + } + } + return sb.toString(); + } + + /** + * 查找指定字符串是否匹配指定字符串列表中的任意一个字符串 + * + * @param str 指定字符串 + * @param strs 需要检查的字符串数组 + * @return 是否匹配 + */ + public static boolean matches(String str, List strs) + { + if (isEmpty(str) || isEmpty(strs)) + { + return false; + } + for (String pattern : strs) + { + if (isMatch(pattern, str)) + { + return true; + } + } + return false; + } + + /** + * 判断url是否与规则配置: + * ? 表示单个字符; + * * 表示一层路径内的任意字符串,不可跨层级; + * ** 表示任意层路径; + * + * @param pattern 匹配规则 + * @param url 需要匹配的url + * @return + */ + public static boolean isMatch(String pattern, String url) + { + AntPathMatcher matcher = new AntPathMatcher(); + return matcher.match(pattern, url); + } + + @SuppressWarnings("unchecked") + public static T cast(Object obj) + { + return (T) obj; + } + + /** + * 数字左边补齐0,使之达到指定长度。注意,如果数字转换为字符串后,长度大于size,则只保留 最后size个字符。 + * + * @param num 数字对象 + * @param size 字符串指定长度 + * @return 返回数字的字符串格式,该字符串为指定长度。 + */ + public static final String padl(final Number num, final int size) + { + return padl(num.toString(), size, '0'); + } + + /** + * 字符串左补齐。如果原始字符串s长度大于size,则只保留最后size个字符。 + * + * @param s 原始字符串 + * @param size 字符串指定长度 + * @param c 用于补齐的字符 + * @return 返回指定长度的字符串,由原字符串左补齐或截取得到。 + */ + public static final String padl(final String s, final int size, final char c) + { + final StringBuilder sb = new StringBuilder(size); + if (s != null) + { + final int len = s.length(); + if (s.length() <= size) + { + for (int i = size - len; i > 0; i--) + { + sb.append(c); + } + sb.append(s); + } + else + { + return s.substring(len - size, len); + } + } + else + { + for (int i = size; i > 0; i--) + { + sb.append(c); + } + } + return sb.toString(); + } +} \ No newline at end of file diff --git a/zzyl-common/src/main/java/com/zzyl/common/utils/Threads.java b/zzyl-common/src/main/java/com/zzyl/common/utils/Threads.java new file mode 100644 index 0000000..3f455e6 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/utils/Threads.java @@ -0,0 +1,99 @@ +package com.zzyl.common.utils; + +import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * 线程相关工具类. + * + * @author ruoyi + */ +public class Threads +{ + private static final Logger logger = LoggerFactory.getLogger(Threads.class); + + /** + * sleep等待,单位为毫秒 + */ + public static void sleep(long milliseconds) + { + try + { + Thread.sleep(milliseconds); + } + catch (InterruptedException e) + { + return; + } + } + + /** + * 停止线程池 + * 先使用shutdown, 停止接收新任务并尝试完成所有已存在任务. + * 如果超时, 则调用shutdownNow, 取消在workQueue中Pending的任务,并中断所有阻塞函数. + * 如果仍然超時,則強制退出. + * 另对在shutdown时线程本身被调用中断做了处理. + */ + public static void shutdownAndAwaitTermination(ExecutorService pool) + { + if (pool != null && !pool.isShutdown()) + { + pool.shutdown(); + try + { + if (!pool.awaitTermination(120, TimeUnit.SECONDS)) + { + pool.shutdownNow(); + if (!pool.awaitTermination(120, TimeUnit.SECONDS)) + { + logger.info("Pool did not terminate"); + } + } + } + catch (InterruptedException ie) + { + pool.shutdownNow(); + Thread.currentThread().interrupt(); + } + } + } + + /** + * 打印线程异常信息 + */ + public static void printException(Runnable r, Throwable t) + { + if (t == null && r instanceof Future) + { + try + { + Future future = (Future) r; + if (future.isDone()) + { + future.get(); + } + } + catch (CancellationException ce) + { + t = ce; + } + catch (ExecutionException ee) + { + t = ee.getCause(); + } + catch (InterruptedException ie) + { + Thread.currentThread().interrupt(); + } + } + if (t != null) + { + logger.error(t.getMessage(), t); + } + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/utils/UserThreadLocal.java b/zzyl-common/src/main/java/com/zzyl/common/utils/UserThreadLocal.java new file mode 100644 index 0000000..b8048aa --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/utils/UserThreadLocal.java @@ -0,0 +1,50 @@ +package com.zzyl.common.utils; + +/** + * 用户线程变量 + * + * @author Zhy + * @version 1.0 + * @date 2025-03-05 12:26 + */ +public class UserThreadLocal { + + private static final ThreadLocal LOCAL = new ThreadLocal<>(); + + private UserThreadLocal() { + + } + + /** + * 将authUserInfo放到ThreadLocal中 + * + * @param authUserInfo {@link Long} + */ + public static void set(Long authUserInfo) { + LOCAL.set(authUserInfo); + } + + /** + * 从ThreadLocal中获取authUserInfo + */ + public static Long get() { + return LOCAL.get(); + } + + /** + * 从当前线程中删除authUserInfo + */ + public static void remove() { + LOCAL.remove(); + } + + /** + * 从当前线程中获取前端用户id + * + * @return 用户id + */ + public static Long getUserId() { + return LOCAL.get(); + } + +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/utils/bean/BeanUtils.java b/zzyl-common/src/main/java/com/zzyl/common/utils/bean/BeanUtils.java new file mode 100644 index 0000000..b9a680e --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/utils/bean/BeanUtils.java @@ -0,0 +1,110 @@ +package com.zzyl.common.utils.bean; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Bean 工具类 + * + * @author ruoyi + */ +public class BeanUtils extends org.springframework.beans.BeanUtils +{ + /** Bean方法名中属性名开始的下标 */ + private static final int BEAN_METHOD_PROP_INDEX = 3; + + /** * 匹配getter方法的正则表达式 */ + private static final Pattern GET_PATTERN = Pattern.compile("get(\\p{javaUpperCase}\\w*)"); + + /** * 匹配setter方法的正则表达式 */ + private static final Pattern SET_PATTERN = Pattern.compile("set(\\p{javaUpperCase}\\w*)"); + + /** + * Bean属性复制工具方法。 + * + * @param dest 目标对象 + * @param src 源对象 + */ + public static void copyBeanProp(Object dest, Object src) + { + try + { + copyProperties(src, dest); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + /** + * 获取对象的setter方法。 + * + * @param obj 对象 + * @return 对象的setter方法列表 + */ + public static List getSetterMethods(Object obj) + { + // setter方法列表 + List setterMethods = new ArrayList(); + + // 获取所有方法 + Method[] methods = obj.getClass().getMethods(); + + // 查找setter方法 + + for (Method method : methods) + { + Matcher m = SET_PATTERN.matcher(method.getName()); + if (m.matches() && (method.getParameterTypes().length == 1)) + { + setterMethods.add(method); + } + } + // 返回setter方法列表 + return setterMethods; + } + + /** + * 获取对象的getter方法。 + * + * @param obj 对象 + * @return 对象的getter方法列表 + */ + + public static List getGetterMethods(Object obj) + { + // getter方法列表 + List getterMethods = new ArrayList(); + // 获取所有方法 + Method[] methods = obj.getClass().getMethods(); + // 查找getter方法 + for (Method method : methods) + { + Matcher m = GET_PATTERN.matcher(method.getName()); + if (m.matches() && (method.getParameterTypes().length == 0)) + { + getterMethods.add(method); + } + } + // 返回getter方法列表 + return getterMethods; + } + + /** + * 检查Bean方法名中的属性名是否相等。
+ * 如getName()和setName()属性名一样,getName()和setAge()属性名不一样。 + * + * @param m1 方法名1 + * @param m2 方法名2 + * @return 属性名一样返回true,否则返回false + */ + + public static boolean isMethodPropEquals(String m1, String m2) + { + return m1.substring(BEAN_METHOD_PROP_INDEX).equals(m2.substring(BEAN_METHOD_PROP_INDEX)); + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/utils/bean/BeanValidators.java b/zzyl-common/src/main/java/com/zzyl/common/utils/bean/BeanValidators.java new file mode 100644 index 0000000..b3f67e4 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/utils/bean/BeanValidators.java @@ -0,0 +1,24 @@ +package com.zzyl.common.utils.bean; + +import java.util.Set; +import javax.validation.ConstraintViolation; +import javax.validation.ConstraintViolationException; +import javax.validation.Validator; + +/** + * bean对象属性验证 + * + * @author ruoyi + */ +public class BeanValidators +{ + public static void validateWithException(Validator validator, Object object, Class... groups) + throws ConstraintViolationException + { + Set> constraintViolations = validator.validate(object, groups); + if (!constraintViolations.isEmpty()) + { + throw new ConstraintViolationException(constraintViolations); + } + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/utils/file/FileTypeUtils.java b/zzyl-common/src/main/java/com/zzyl/common/utils/file/FileTypeUtils.java new file mode 100644 index 0000000..e3e42f8 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/utils/file/FileTypeUtils.java @@ -0,0 +1,76 @@ +package com.zzyl.common.utils.file; + +import java.io.File; +import org.apache.commons.lang3.StringUtils; + +/** + * 文件类型工具类 + * + * @author ruoyi + */ +public class FileTypeUtils +{ + /** + * 获取文件类型 + *

+ * 例如: ruoyi.txt, 返回: txt + * + * @param file 文件名 + * @return 后缀(不含".") + */ + public static String getFileType(File file) + { + if (null == file) + { + return StringUtils.EMPTY; + } + return getFileType(file.getName()); + } + + /** + * 获取文件类型 + *

+ * 例如: ruoyi.txt, 返回: txt + * + * @param fileName 文件名 + * @return 后缀(不含".") + */ + public static String getFileType(String fileName) + { + int separatorIndex = fileName.lastIndexOf("."); + if (separatorIndex < 0) + { + return ""; + } + return fileName.substring(separatorIndex + 1).toLowerCase(); + } + + /** + * 获取文件类型 + * + * @param photoByte 文件字节码 + * @return 后缀(不含".") + */ + public static String getFileExtendName(byte[] photoByte) + { + String strFileExtendName = "JPG"; + if ((photoByte[0] == 71) && (photoByte[1] == 73) && (photoByte[2] == 70) && (photoByte[3] == 56) + && ((photoByte[4] == 55) || (photoByte[4] == 57)) && (photoByte[5] == 97)) + { + strFileExtendName = "GIF"; + } + else if ((photoByte[6] == 74) && (photoByte[7] == 70) && (photoByte[8] == 73) && (photoByte[9] == 70)) + { + strFileExtendName = "JPG"; + } + else if ((photoByte[0] == 66) && (photoByte[1] == 77)) + { + strFileExtendName = "BMP"; + } + else if ((photoByte[1] == 80) && (photoByte[2] == 78) && (photoByte[3] == 71)) + { + strFileExtendName = "PNG"; + } + return strFileExtendName; + } +} \ No newline at end of file diff --git a/zzyl-common/src/main/java/com/zzyl/common/utils/file/FileUploadUtils.java b/zzyl-common/src/main/java/com/zzyl/common/utils/file/FileUploadUtils.java new file mode 100644 index 0000000..d8b640d --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/utils/file/FileUploadUtils.java @@ -0,0 +1,232 @@ +package com.zzyl.common.utils.file; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Paths; +import java.util.Objects; +import org.apache.commons.io.FilenameUtils; +import org.springframework.web.multipart.MultipartFile; +import com.zzyl.common.config.RuoYiConfig; +import com.zzyl.common.constant.Constants; +import com.zzyl.common.exception.file.FileNameLengthLimitExceededException; +import com.zzyl.common.exception.file.FileSizeLimitExceededException; +import com.zzyl.common.exception.file.InvalidExtensionException; +import com.zzyl.common.utils.DateUtils; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.common.utils.uuid.Seq; + +/** + * 文件上传工具类 + * + * @author ruoyi + */ +public class FileUploadUtils +{ + /** + * 默认大小 50M + */ + public static final long DEFAULT_MAX_SIZE = 50 * 1024 * 1024L; + + /** + * 默认的文件名最大长度 100 + */ + public static final int DEFAULT_FILE_NAME_LENGTH = 100; + + /** + * 默认上传的地址 + */ + private static String defaultBaseDir = RuoYiConfig.getProfile(); + + public static void setDefaultBaseDir(String defaultBaseDir) + { + FileUploadUtils.defaultBaseDir = defaultBaseDir; + } + + public static String getDefaultBaseDir() + { + return defaultBaseDir; + } + + /** + * 以默认配置进行文件上传 + * + * @param file 上传的文件 + * @return 文件名称 + * @throws Exception + */ + public static final String upload(MultipartFile file) throws IOException + { + try + { + return upload(getDefaultBaseDir(), file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION); + } + catch (Exception e) + { + throw new IOException(e.getMessage(), e); + } + } + + /** + * 根据文件路径上传 + * + * @param baseDir 相对应用的基目录 + * @param file 上传的文件 + * @return 文件名称 + * @throws IOException + */ + public static final String upload(String baseDir, MultipartFile file) throws IOException + { + try + { + return upload(baseDir, file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION); + } + catch (Exception e) + { + throw new IOException(e.getMessage(), e); + } + } + + /** + * 文件上传 + * + * @param baseDir 相对应用的基目录 + * @param file 上传的文件 + * @param allowedExtension 上传文件类型 + * @return 返回上传成功的文件名 + * @throws FileSizeLimitExceededException 如果超出最大大小 + * @throws FileNameLengthLimitExceededException 文件名太长 + * @throws IOException 比如读写文件出错时 + * @throws InvalidExtensionException 文件校验异常 + */ + public static final String upload(String baseDir, MultipartFile file, String[] allowedExtension) + throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException, + InvalidExtensionException + { + int fileNamelength = Objects.requireNonNull(file.getOriginalFilename()).length(); + if (fileNamelength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH) + { + throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH); + } + + assertAllowed(file, allowedExtension); + + String fileName = extractFilename(file); + + String absPath = getAbsoluteFile(baseDir, fileName).getAbsolutePath(); + file.transferTo(Paths.get(absPath)); + return getPathFileName(baseDir, fileName); + } + + /** + * 编码文件名 + */ + public static final String extractFilename(MultipartFile file) + { + return StringUtils.format("{}/{}_{}.{}", DateUtils.datePath(), + FilenameUtils.getBaseName(file.getOriginalFilename()), Seq.getId(Seq.uploadSeqType), getExtension(file)); + } + + public static final File getAbsoluteFile(String uploadDir, String fileName) throws IOException + { + File desc = new File(uploadDir + File.separator + fileName); + + if (!desc.exists()) + { + if (!desc.getParentFile().exists()) + { + desc.getParentFile().mkdirs(); + } + } + return desc; + } + + public static final String getPathFileName(String uploadDir, String fileName) throws IOException + { + int dirLastIndex = RuoYiConfig.getProfile().length() + 1; + String currentDir = StringUtils.substring(uploadDir, dirLastIndex); + return Constants.RESOURCE_PREFIX + "/" + currentDir + "/" + fileName; + } + + /** + * 文件大小校验 + * + * @param file 上传的文件 + * @return + * @throws FileSizeLimitExceededException 如果超出最大大小 + * @throws InvalidExtensionException + */ + public static final void assertAllowed(MultipartFile file, String[] allowedExtension) + throws FileSizeLimitExceededException, InvalidExtensionException + { + long size = file.getSize(); + if (size > DEFAULT_MAX_SIZE) + { + throw new FileSizeLimitExceededException(DEFAULT_MAX_SIZE / 1024 / 1024); + } + + String fileName = file.getOriginalFilename(); + String extension = getExtension(file); + if (allowedExtension != null && !isAllowedExtension(extension, allowedExtension)) + { + if (allowedExtension == MimeTypeUtils.IMAGE_EXTENSION) + { + throw new InvalidExtensionException.InvalidImageExtensionException(allowedExtension, extension, + fileName); + } + else if (allowedExtension == MimeTypeUtils.FLASH_EXTENSION) + { + throw new InvalidExtensionException.InvalidFlashExtensionException(allowedExtension, extension, + fileName); + } + else if (allowedExtension == MimeTypeUtils.MEDIA_EXTENSION) + { + throw new InvalidExtensionException.InvalidMediaExtensionException(allowedExtension, extension, + fileName); + } + else if (allowedExtension == MimeTypeUtils.VIDEO_EXTENSION) + { + throw new InvalidExtensionException.InvalidVideoExtensionException(allowedExtension, extension, + fileName); + } + else + { + throw new InvalidExtensionException(allowedExtension, extension, fileName); + } + } + } + + /** + * 判断MIME类型是否是允许的MIME类型 + * + * @param extension + * @param allowedExtension + * @return + */ + public static final boolean isAllowedExtension(String extension, String[] allowedExtension) + { + for (String str : allowedExtension) + { + if (str.equalsIgnoreCase(extension)) + { + return true; + } + } + return false; + } + + /** + * 获取文件名的后缀 + * + * @param file 表单文件 + * @return 后缀名 + */ + public static final String getExtension(MultipartFile file) + { + String extension = FilenameUtils.getExtension(file.getOriginalFilename()); + if (StringUtils.isEmpty(extension)) + { + extension = MimeTypeUtils.getExtension(Objects.requireNonNull(file.getContentType())); + } + return extension; + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/utils/file/FileUtils.java b/zzyl-common/src/main/java/com/zzyl/common/utils/file/FileUtils.java new file mode 100644 index 0000000..a36f022 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/utils/file/FileUtils.java @@ -0,0 +1,291 @@ +package com.zzyl.common.utils.file; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.ArrayUtils; +import com.zzyl.common.config.RuoYiConfig; +import com.zzyl.common.utils.DateUtils; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.common.utils.uuid.IdUtils; +import org.apache.commons.io.FilenameUtils; + +/** + * 文件处理工具类 + * + * @author ruoyi + */ +public class FileUtils +{ + public static String FILENAME_PATTERN = "[a-zA-Z0-9_\\-\\|\\.\\u4e00-\\u9fa5]+"; + + /** + * 输出指定文件的byte数组 + * + * @param filePath 文件路径 + * @param os 输出流 + * @return + */ + public static void writeBytes(String filePath, OutputStream os) throws IOException + { + FileInputStream fis = null; + try + { + File file = new File(filePath); + if (!file.exists()) + { + throw new FileNotFoundException(filePath); + } + fis = new FileInputStream(file); + byte[] b = new byte[1024]; + int length; + while ((length = fis.read(b)) > 0) + { + os.write(b, 0, length); + } + } + catch (IOException e) + { + throw e; + } + finally + { + IOUtils.close(os); + IOUtils.close(fis); + } + } + + /** + * 写数据到文件中 + * + * @param data 数据 + * @return 目标文件 + * @throws IOException IO异常 + */ + public static String writeImportBytes(byte[] data) throws IOException + { + return writeBytes(data, RuoYiConfig.getImportPath()); + } + + /** + * 写数据到文件中 + * + * @param data 数据 + * @param uploadDir 目标文件 + * @return 目标文件 + * @throws IOException IO异常 + */ + public static String writeBytes(byte[] data, String uploadDir) throws IOException + { + FileOutputStream fos = null; + String pathName = ""; + try + { + String extension = getFileExtendName(data); + pathName = DateUtils.datePath() + "/" + IdUtils.fastUUID() + "." + extension; + File file = FileUploadUtils.getAbsoluteFile(uploadDir, pathName); + fos = new FileOutputStream(file); + fos.write(data); + } + finally + { + IOUtils.close(fos); + } + return FileUploadUtils.getPathFileName(uploadDir, pathName); + } + + /** + * 删除文件 + * + * @param filePath 文件 + * @return + */ + public static boolean deleteFile(String filePath) + { + boolean flag = false; + File file = new File(filePath); + // 路径为文件且不为空则进行删除 + if (file.isFile() && file.exists()) + { + flag = file.delete(); + } + return flag; + } + + /** + * 文件名称验证 + * + * @param filename 文件名称 + * @return true 正常 false 非法 + */ + public static boolean isValidFilename(String filename) + { + return filename.matches(FILENAME_PATTERN); + } + + /** + * 检查文件是否可下载 + * + * @param resource 需要下载的文件 + * @return true 正常 false 非法 + */ + public static boolean checkAllowDownload(String resource) + { + // 禁止目录上跳级别 + if (StringUtils.contains(resource, "..")) + { + return false; + } + + // 检查允许下载的文件规则 + if (ArrayUtils.contains(MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION, FileTypeUtils.getFileType(resource))) + { + return true; + } + + // 不在允许下载的文件规则 + return false; + } + + /** + * 下载文件名重新编码 + * + * @param request 请求对象 + * @param fileName 文件名 + * @return 编码后的文件名 + */ + public static String setFileDownloadHeader(HttpServletRequest request, String fileName) throws UnsupportedEncodingException + { + final String agent = request.getHeader("USER-AGENT"); + String filename = fileName; + if (agent.contains("MSIE")) + { + // IE浏览器 + filename = URLEncoder.encode(filename, "utf-8"); + filename = filename.replace("+", " "); + } + else if (agent.contains("Firefox")) + { + // 火狐浏览器 + filename = new String(fileName.getBytes(), "ISO8859-1"); + } + else if (agent.contains("Chrome")) + { + // google浏览器 + filename = URLEncoder.encode(filename, "utf-8"); + } + else + { + // 其它浏览器 + filename = URLEncoder.encode(filename, "utf-8"); + } + return filename; + } + + /** + * 下载文件名重新编码 + * + * @param response 响应对象 + * @param realFileName 真实文件名 + */ + public static void setAttachmentResponseHeader(HttpServletResponse response, String realFileName) throws UnsupportedEncodingException + { + String percentEncodedFileName = percentEncode(realFileName); + + StringBuilder contentDispositionValue = new StringBuilder(); + contentDispositionValue.append("attachment; filename=") + .append(percentEncodedFileName) + .append(";") + .append("filename*=") + .append("utf-8''") + .append(percentEncodedFileName); + + response.addHeader("Access-Control-Expose-Headers", "Content-Disposition,download-filename"); + response.setHeader("Content-disposition", contentDispositionValue.toString()); + response.setHeader("download-filename", percentEncodedFileName); + } + + /** + * 百分号编码工具方法 + * + * @param s 需要百分号编码的字符串 + * @return 百分号编码后的字符串 + */ + public static String percentEncode(String s) throws UnsupportedEncodingException + { + String encode = URLEncoder.encode(s, StandardCharsets.UTF_8.toString()); + return encode.replaceAll("\\+", "%20"); + } + + /** + * 获取图像后缀 + * + * @param photoByte 图像数据 + * @return 后缀名 + */ + public static String getFileExtendName(byte[] photoByte) + { + String strFileExtendName = "jpg"; + if ((photoByte[0] == 71) && (photoByte[1] == 73) && (photoByte[2] == 70) && (photoByte[3] == 56) + && ((photoByte[4] == 55) || (photoByte[4] == 57)) && (photoByte[5] == 97)) + { + strFileExtendName = "gif"; + } + else if ((photoByte[6] == 74) && (photoByte[7] == 70) && (photoByte[8] == 73) && (photoByte[9] == 70)) + { + strFileExtendName = "jpg"; + } + else if ((photoByte[0] == 66) && (photoByte[1] == 77)) + { + strFileExtendName = "bmp"; + } + else if ((photoByte[1] == 80) && (photoByte[2] == 78) && (photoByte[3] == 71)) + { + strFileExtendName = "png"; + } + return strFileExtendName; + } + + /** + * 获取文件名称 /profile/upload/2022/04/16/ruoyi.png -- ruoyi.png + * + * @param fileName 路径名称 + * @return 没有文件路径的名称 + */ + public static String getName(String fileName) + { + if (fileName == null) + { + return null; + } + int lastUnixPos = fileName.lastIndexOf('/'); + int lastWindowsPos = fileName.lastIndexOf('\\'); + int index = Math.max(lastUnixPos, lastWindowsPos); + return fileName.substring(index + 1); + } + + /** + * 获取不带后缀文件名称 /profile/upload/2022/04/16/ruoyi.png -- ruoyi + * + * @param fileName 路径名称 + * @return 没有文件路径和后缀的名称 + */ + public static String getNameNotSuffix(String fileName) + { + if (fileName == null) + { + return null; + } + String baseName = FilenameUtils.getBaseName(fileName); + return baseName; + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/utils/file/ImageUtils.java b/zzyl-common/src/main/java/com/zzyl/common/utils/file/ImageUtils.java new file mode 100644 index 0000000..d970aac --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/utils/file/ImageUtils.java @@ -0,0 +1,98 @@ +package com.zzyl.common.utils.file; + +import java.io.ByteArrayInputStream; +import java.io.FileInputStream; +import java.io.InputStream; +import java.net.URL; +import java.net.URLConnection; +import java.util.Arrays; +import org.apache.poi.util.IOUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.zzyl.common.config.RuoYiConfig; +import com.zzyl.common.constant.Constants; +import com.zzyl.common.utils.StringUtils; + +/** + * 图片处理工具类 + * + * @author ruoyi + */ +public class ImageUtils +{ + private static final Logger log = LoggerFactory.getLogger(ImageUtils.class); + + public static byte[] getImage(String imagePath) + { + InputStream is = getFile(imagePath); + try + { + return IOUtils.toByteArray(is); + } + catch (Exception e) + { + log.error("图片加载异常 {}", e); + return null; + } + finally + { + IOUtils.closeQuietly(is); + } + } + + public static InputStream getFile(String imagePath) + { + try + { + byte[] result = readFile(imagePath); + result = Arrays.copyOf(result, result.length); + return new ByteArrayInputStream(result); + } + catch (Exception e) + { + log.error("获取图片异常 {}", e); + } + return null; + } + + /** + * 读取文件为字节数据 + * + * @param url 地址 + * @return 字节数据 + */ + public static byte[] readFile(String url) + { + InputStream in = null; + try + { + if (url.startsWith("http")) + { + // 网络地址 + URL urlObj = new URL(url); + URLConnection urlConnection = urlObj.openConnection(); + urlConnection.setConnectTimeout(30 * 1000); + urlConnection.setReadTimeout(60 * 1000); + urlConnection.setDoInput(true); + in = urlConnection.getInputStream(); + } + else + { + // 本机地址 + String localPath = RuoYiConfig.getProfile(); + String downloadPath = localPath + StringUtils.substringAfter(url, Constants.RESOURCE_PREFIX); + in = new FileInputStream(downloadPath); + } + return IOUtils.toByteArray(in); + } + catch (Exception e) + { + log.error("获取文件路径异常 {}", e); + return null; + } + finally + { + IOUtils.closeQuietly(in); + } + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/utils/file/MimeTypeUtils.java b/zzyl-common/src/main/java/com/zzyl/common/utils/file/MimeTypeUtils.java new file mode 100644 index 0000000..a911274 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/utils/file/MimeTypeUtils.java @@ -0,0 +1,59 @@ +package com.zzyl.common.utils.file; + +/** + * 媒体类型工具类 + * + * @author ruoyi + */ +public class MimeTypeUtils +{ + public static final String IMAGE_PNG = "image/png"; + + public static final String IMAGE_JPG = "image/jpg"; + + public static final String IMAGE_JPEG = "image/jpeg"; + + public static final String IMAGE_BMP = "image/bmp"; + + public static final String IMAGE_GIF = "image/gif"; + + public static final String[] IMAGE_EXTENSION = { "bmp", "gif", "jpg", "jpeg", "png" }; + + public static final String[] FLASH_EXTENSION = { "swf", "flv" }; + + public static final String[] MEDIA_EXTENSION = { "swf", "flv", "mp3", "wav", "wma", "wmv", "mid", "avi", "mpg", + "asf", "rm", "rmvb" }; + + public static final String[] VIDEO_EXTENSION = { "mp4", "avi", "rmvb" }; + + public static final String[] DEFAULT_ALLOWED_EXTENSION = { + // 图片 + "bmp", "gif", "jpg", "jpeg", "png", + // word excel powerpoint + "doc", "docx", "xls", "xlsx", "ppt", "pptx", "html", "htm", "txt", + // 压缩文件 + "rar", "zip", "gz", "bz2", + // 视频格式 + "mp4", "avi", "rmvb", + // pdf + "pdf" }; + + public static String getExtension(String prefix) + { + switch (prefix) + { + case IMAGE_PNG: + return "png"; + case IMAGE_JPG: + return "jpg"; + case IMAGE_JPEG: + return "jpeg"; + case IMAGE_BMP: + return "bmp"; + case IMAGE_GIF: + return "gif"; + default: + return ""; + } + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/utils/html/EscapeUtil.java b/zzyl-common/src/main/java/com/zzyl/common/utils/html/EscapeUtil.java new file mode 100644 index 0000000..9b2d1db --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/utils/html/EscapeUtil.java @@ -0,0 +1,172 @@ +package com.zzyl.common.utils.html; + +import com.zzyl.common.utils.StringUtils; + +/** + * 转义和反转义工具类 + * + * @author ruoyi + */ +public class EscapeUtil +{ + public static final String RE_HTML_MARK = "(<[^<]*?>)|(<[\\s]*?/[^<]*?>)|(<[^<]*?/[\\s]*?>)"; + + private static final char[][] TEXT = new char[64][]; + + static + { + for (int i = 0; i < 64; i++) + { + TEXT[i] = new char[] { (char) i }; + } + + // special HTML characters + // 单引号 + TEXT['\''] = "'".toCharArray(); + // 双引号 + TEXT['"'] = """.toCharArray(); + // &符 + TEXT['&'] = "&".toCharArray(); + // 小于号 + TEXT['<'] = "<".toCharArray(); + // 大于号 + TEXT['>'] = ">".toCharArray(); + } + + /** + * 转义文本中的HTML字符为安全的字符 + * + * @param text 被转义的文本 + * @return 转义后的文本 + */ + public static String escape(String text) + { + return encode(text); + } + + /** + * 还原被转义的HTML特殊字符 + * + * @param content 包含转义符的HTML内容 + * @return 转换后的字符串 + */ + public static String unescape(String content) + { + return decode(content); + } + + /** + * 清除所有HTML标签,但是不删除标签内的内容 + * + * @param content 文本 + * @return 清除标签后的文本 + */ + public static String clean(String content) + { + return new HTMLFilter().filter(content); + } + + /** + * Escape编码 + * + * @param text 被编码的文本 + * @return 编码后的字符 + */ + private static String encode(String text) + { + if (StringUtils.isEmpty(text)) + { + return StringUtils.EMPTY; + } + + final StringBuilder tmp = new StringBuilder(text.length() * 6); + char c; + for (int i = 0; i < text.length(); i++) + { + c = text.charAt(i); + if (c < 256) + { + tmp.append("%"); + if (c < 16) + { + tmp.append("0"); + } + tmp.append(Integer.toString(c, 16)); + } + else + { + tmp.append("%u"); + if (c <= 0xfff) + { + // issue#I49JU8@Gitee + tmp.append("0"); + } + tmp.append(Integer.toString(c, 16)); + } + } + return tmp.toString(); + } + + /** + * Escape解码 + * + * @param content 被转义的内容 + * @return 解码后的字符串 + */ + public static String decode(String content) + { + if (StringUtils.isEmpty(content)) + { + return content; + } + + StringBuilder tmp = new StringBuilder(content.length()); + int lastPos = 0, pos = 0; + char ch; + while (lastPos < content.length()) + { + pos = content.indexOf("%", lastPos); + if (pos == lastPos) + { + if (content.charAt(pos + 1) == 'u') + { + ch = (char) Integer.parseInt(content.substring(pos + 2, pos + 6), 16); + tmp.append(ch); + lastPos = pos + 6; + } + else + { + ch = (char) Integer.parseInt(content.substring(pos + 1, pos + 3), 16); + tmp.append(ch); + lastPos = pos + 3; + } + } + else + { + if (pos == -1) + { + tmp.append(content.substring(lastPos)); + lastPos = content.length(); + } + else + { + tmp.append(content.substring(lastPos, pos)); + lastPos = pos; + } + } + } + return tmp.toString(); + } + + public static void main(String[] args) + { + String html = ""; + String escape = EscapeUtil.escape(html); + // String html = "ipt>alert(\"XSS\")ipt>"; + // String html = "<123"; + // String html = "123>"; + System.out.println("clean: " + EscapeUtil.clean(html)); + System.out.println("escape: " + escape); + System.out.println("unescape: " + EscapeUtil.unescape(escape)); + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/utils/html/HTMLFilter.java b/zzyl-common/src/main/java/com/zzyl/common/utils/html/HTMLFilter.java new file mode 100644 index 0000000..8894fc5 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/utils/html/HTMLFilter.java @@ -0,0 +1,581 @@ +package com.zzyl.common.utils.html; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * HTML过滤器,用于去除XSS漏洞隐患。 + * + * @author ruoyi + */ +public final class HTMLFilter +{ + /** + * regex flag union representing /si modifiers in php + **/ + private static final int REGEX_FLAGS_SI = Pattern.CASE_INSENSITIVE | Pattern.DOTALL; + private static final Pattern P_COMMENTS = Pattern.compile("", Pattern.DOTALL); + private static final Pattern P_COMMENT = Pattern.compile("^!--(.*)--$", REGEX_FLAGS_SI); + private static final Pattern P_TAGS = Pattern.compile("<(.*?)>", Pattern.DOTALL); + private static final Pattern P_END_TAG = Pattern.compile("^/([a-z0-9]+)", REGEX_FLAGS_SI); + private static final Pattern P_START_TAG = Pattern.compile("^([a-z0-9]+)(.*?)(/?)$", REGEX_FLAGS_SI); + private static final Pattern P_QUOTED_ATTRIBUTES = Pattern.compile("([a-z0-9]+)=([\"'])(.*?)\\2", REGEX_FLAGS_SI); + private static final Pattern P_UNQUOTED_ATTRIBUTES = Pattern.compile("([a-z0-9]+)(=)([^\"\\s']+)", REGEX_FLAGS_SI); + private static final Pattern P_PROTOCOL = Pattern.compile("^([^:]+):", REGEX_FLAGS_SI); + private static final Pattern P_ENTITY = Pattern.compile("&#(\\d+);?"); + private static final Pattern P_ENTITY_UNICODE = Pattern.compile("&#x([0-9a-f]+);?"); + private static final Pattern P_ENCODE = Pattern.compile("%([0-9a-f]{2});?"); + private static final Pattern P_VALID_ENTITIES = Pattern.compile("&([^&;]*)(?=(;|&|$))"); + private static final Pattern P_VALID_QUOTES = Pattern.compile("(>|^)([^<]+?)(<|$)", Pattern.DOTALL); + private static final Pattern P_END_ARROW = Pattern.compile("^>"); + private static final Pattern P_BODY_TO_END = Pattern.compile("<([^>]*?)(?=<|$)"); + private static final Pattern P_XML_CONTENT = Pattern.compile("(^|>)([^<]*?)(?=>)"); + private static final Pattern P_STRAY_LEFT_ARROW = Pattern.compile("<([^>]*?)(?=<|$)"); + private static final Pattern P_STRAY_RIGHT_ARROW = Pattern.compile("(^|>)([^<]*?)(?=>)"); + private static final Pattern P_AMP = Pattern.compile("&"); + private static final Pattern P_QUOTE = Pattern.compile("\""); + private static final Pattern P_LEFT_ARROW = Pattern.compile("<"); + private static final Pattern P_RIGHT_ARROW = Pattern.compile(">"); + private static final Pattern P_BOTH_ARROWS = Pattern.compile("<>"); + + // @xxx could grow large... maybe use sesat's ReferenceMap + private static final ConcurrentMap P_REMOVE_PAIR_BLANKS = new ConcurrentHashMap<>(); + private static final ConcurrentMap P_REMOVE_SELF_BLANKS = new ConcurrentHashMap<>(); + + /** + * set of allowed html elements, along with allowed attributes for each element + **/ + private final Map> vAllowed; + /** + * counts of open tags for each (allowable) html element + **/ + private final Map vTagCounts = new HashMap<>(); + + /** + * html elements which must always be self-closing (e.g. "") + **/ + private final String[] vSelfClosingTags; + /** + * html elements which must always have separate opening and closing tags (e.g. "") + **/ + private final String[] vNeedClosingTags; + /** + * set of disallowed html elements + **/ + private final String[] vDisallowed; + /** + * attributes which should be checked for valid protocols + **/ + private final String[] vProtocolAtts; + /** + * allowed protocols + **/ + private final String[] vAllowedProtocols; + /** + * tags which should be removed if they contain no content (e.g. "" or "") + **/ + private final String[] vRemoveBlanks; + /** + * entities allowed within html markup + **/ + private final String[] vAllowedEntities; + /** + * flag determining whether comments are allowed in input String. + */ + private final boolean stripComment; + private final boolean encodeQuotes; + /** + * flag determining whether to try to make tags when presented with "unbalanced" angle brackets (e.g. "" + * becomes " text "). If set to false, unbalanced angle brackets will be html escaped. + */ + private final boolean alwaysMakeTags; + + /** + * Default constructor. + */ + public HTMLFilter() + { + vAllowed = new HashMap<>(); + + final ArrayList a_atts = new ArrayList<>(); + a_atts.add("href"); + a_atts.add("target"); + vAllowed.put("a", a_atts); + + final ArrayList img_atts = new ArrayList<>(); + img_atts.add("src"); + img_atts.add("width"); + img_atts.add("height"); + img_atts.add("alt"); + vAllowed.put("img", img_atts); + + final ArrayList no_atts = new ArrayList<>(); + vAllowed.put("b", no_atts); + vAllowed.put("strong", no_atts); + vAllowed.put("i", no_atts); + vAllowed.put("em", no_atts); + + vSelfClosingTags = new String[] { "img" }; + vNeedClosingTags = new String[] { "a", "b", "strong", "i", "em" }; + vDisallowed = new String[] {}; + // no ftp. + vAllowedProtocols = new String[] { "http", "mailto", "https" }; + vProtocolAtts = new String[] { "src", "href" }; + vRemoveBlanks = new String[] { "a", "b", "strong", "i", "em" }; + vAllowedEntities = new String[] { "amp", "gt", "lt", "quot" }; + stripComment = true; + encodeQuotes = true; + alwaysMakeTags = false; + } + + /** + * Map-parameter configurable constructor. + * + * @param conf map containing configuration. keys match field names. + */ + @SuppressWarnings("unchecked") + public HTMLFilter(final Map conf) + { + + assert conf.containsKey("vAllowed") : "configuration requires vAllowed"; + assert conf.containsKey("vSelfClosingTags") : "configuration requires vSelfClosingTags"; + assert conf.containsKey("vNeedClosingTags") : "configuration requires vNeedClosingTags"; + assert conf.containsKey("vDisallowed") : "configuration requires vDisallowed"; + assert conf.containsKey("vAllowedProtocols") : "configuration requires vAllowedProtocols"; + assert conf.containsKey("vProtocolAtts") : "configuration requires vProtocolAtts"; + assert conf.containsKey("vRemoveBlanks") : "configuration requires vRemoveBlanks"; + assert conf.containsKey("vAllowedEntities") : "configuration requires vAllowedEntities"; + + vAllowed = Collections.unmodifiableMap((HashMap>) conf.get("vAllowed")); + vSelfClosingTags = (String[]) conf.get("vSelfClosingTags"); + vNeedClosingTags = (String[]) conf.get("vNeedClosingTags"); + vDisallowed = (String[]) conf.get("vDisallowed"); + vAllowedProtocols = (String[]) conf.get("vAllowedProtocols"); + vProtocolAtts = (String[]) conf.get("vProtocolAtts"); + vRemoveBlanks = (String[]) conf.get("vRemoveBlanks"); + vAllowedEntities = (String[]) conf.get("vAllowedEntities"); + stripComment = conf.containsKey("stripComment") ? (Boolean) conf.get("stripComment") : true; + encodeQuotes = conf.containsKey("encodeQuotes") ? (Boolean) conf.get("encodeQuotes") : true; + alwaysMakeTags = conf.containsKey("alwaysMakeTags") ? (Boolean) conf.get("alwaysMakeTags") : true; + } + + private void reset() + { + vTagCounts.clear(); + } + + // --------------------------------------------------------------- + // my versions of some PHP library functions + public static String chr(final int decimal) + { + return String.valueOf((char) decimal); + } + + public static String htmlSpecialChars(final String s) + { + String result = s; + result = regexReplace(P_AMP, "&", result); + result = regexReplace(P_QUOTE, """, result); + result = regexReplace(P_LEFT_ARROW, "<", result); + result = regexReplace(P_RIGHT_ARROW, ">", result); + return result; + } + + // --------------------------------------------------------------- + + /** + * given a user submitted input String, filter out any invalid or restricted html. + * + * @param input text (i.e. submitted by a user) than may contain html + * @return "clean" version of input, with only valid, whitelisted html elements allowed + */ + public String filter(final String input) + { + reset(); + String s = input; + + s = escapeComments(s); + + s = balanceHTML(s); + + s = checkTags(s); + + s = processRemoveBlanks(s); + + // s = validateEntities(s); + + return s; + } + + public boolean isAlwaysMakeTags() + { + return alwaysMakeTags; + } + + public boolean isStripComments() + { + return stripComment; + } + + private String escapeComments(final String s) + { + final Matcher m = P_COMMENTS.matcher(s); + final StringBuffer buf = new StringBuffer(); + if (m.find()) + { + // (.*?) + final String match = m.group(1); + m.appendReplacement(buf, Matcher.quoteReplacement("")); + } + m.appendTail(buf); + + return buf.toString(); + } + + private String balanceHTML(String s) + { + if (alwaysMakeTags) + { + // + // try and form html + // + s = regexReplace(P_END_ARROW, "", s); + // 不追加结束标签 + s = regexReplace(P_BODY_TO_END, "<$1>", s); + s = regexReplace(P_XML_CONTENT, "$1<$2", s); + + } + else + { + // + // escape stray brackets + // + s = regexReplace(P_STRAY_LEFT_ARROW, "<$1", s); + s = regexReplace(P_STRAY_RIGHT_ARROW, "$1$2><", s); + + // + // the last regexp causes '<>' entities to appear + // (we need to do a lookahead assertion so that the last bracket can + // be used in the next pass of the regexp) + // + s = regexReplace(P_BOTH_ARROWS, "", s); + } + + return s; + } + + private String checkTags(String s) + { + Matcher m = P_TAGS.matcher(s); + + final StringBuffer buf = new StringBuffer(); + while (m.find()) + { + String replaceStr = m.group(1); + replaceStr = processTag(replaceStr); + m.appendReplacement(buf, Matcher.quoteReplacement(replaceStr)); + } + m.appendTail(buf); + + // these get tallied in processTag + // (remember to reset before subsequent calls to filter method) + final StringBuilder sBuilder = new StringBuilder(buf.toString()); + for (String key : vTagCounts.keySet()) + { + for (int ii = 0; ii < vTagCounts.get(key); ii++) + { + sBuilder.append(""); + } + } + s = sBuilder.toString(); + + return s; + } + + private String processRemoveBlanks(final String s) + { + String result = s; + for (String tag : vRemoveBlanks) + { + if (!P_REMOVE_PAIR_BLANKS.containsKey(tag)) + { + P_REMOVE_PAIR_BLANKS.putIfAbsent(tag, Pattern.compile("<" + tag + "(\\s[^>]*)?>")); + } + result = regexReplace(P_REMOVE_PAIR_BLANKS.get(tag), "", result); + if (!P_REMOVE_SELF_BLANKS.containsKey(tag)) + { + P_REMOVE_SELF_BLANKS.putIfAbsent(tag, Pattern.compile("<" + tag + "(\\s[^>]*)?/>")); + } + result = regexReplace(P_REMOVE_SELF_BLANKS.get(tag), "", result); + } + + return result; + } + + private static String regexReplace(final Pattern regex_pattern, final String replacement, final String s) + { + Matcher m = regex_pattern.matcher(s); + return m.replaceAll(replacement); + } + + private String processTag(final String s) + { + // ending tags + Matcher m = P_END_TAG.matcher(s); + if (m.find()) + { + final String name = m.group(1).toLowerCase(); + if (allowed(name)) + { + if (!inArray(name, vSelfClosingTags)) + { + if (vTagCounts.containsKey(name)) + { + vTagCounts.put(name, vTagCounts.get(name) - 1); + return ""; + } + } + } + } + + // starting tags + m = P_START_TAG.matcher(s); + if (m.find()) + { + final String name = m.group(1).toLowerCase(); + final String body = m.group(2); + String ending = m.group(3); + + // debug( "in a starting tag, name='" + name + "'; body='" + body + "'; ending='" + ending + "'" ); + if (allowed(name)) + { + final StringBuilder params = new StringBuilder(); + + final Matcher m2 = P_QUOTED_ATTRIBUTES.matcher(body); + final Matcher m3 = P_UNQUOTED_ATTRIBUTES.matcher(body); + final List paramNames = new ArrayList<>(); + final List paramValues = new ArrayList<>(); + while (m2.find()) + { + // ([a-z0-9]+) + paramNames.add(m2.group(1)); + // (.*?) + paramValues.add(m2.group(3)); + } + while (m3.find()) + { + // ([a-z0-9]+) + paramNames.add(m3.group(1)); + // ([^\"\\s']+) + paramValues.add(m3.group(3)); + } + + String paramName, paramValue; + for (int ii = 0; ii < paramNames.size(); ii++) + { + paramName = paramNames.get(ii).toLowerCase(); + paramValue = paramValues.get(ii); + + // debug( "paramName='" + paramName + "'" ); + // debug( "paramValue='" + paramValue + "'" ); + // debug( "allowed? " + vAllowed.get( name ).contains( paramName ) ); + + if (allowedAttribute(name, paramName)) + { + if (inArray(paramName, vProtocolAtts)) + { + paramValue = processParamProtocol(paramValue); + } + params.append(' ').append(paramName).append("=\\\"").append(paramValue).append("\\\""); + } + } + + if (inArray(name, vSelfClosingTags)) + { + ending = " /"; + } + + if (inArray(name, vNeedClosingTags)) + { + ending = ""; + } + + if (ending == null || ending.length() < 1) + { + if (vTagCounts.containsKey(name)) + { + vTagCounts.put(name, vTagCounts.get(name) + 1); + } + else + { + vTagCounts.put(name, 1); + } + } + else + { + ending = " /"; + } + return "<" + name + params + ending + ">"; + } + else + { + return ""; + } + } + + // comments + m = P_COMMENT.matcher(s); + if (!stripComment && m.find()) + { + return "<" + m.group() + ">"; + } + + return ""; + } + + private String processParamProtocol(String s) + { + s = decodeEntities(s); + final Matcher m = P_PROTOCOL.matcher(s); + if (m.find()) + { + final String protocol = m.group(1); + if (!inArray(protocol, vAllowedProtocols)) + { + // bad protocol, turn into local anchor link instead + s = "#" + s.substring(protocol.length() + 1); + if (s.startsWith("#//")) + { + s = "#" + s.substring(3); + } + } + } + + return s; + } + + private String decodeEntities(String s) + { + StringBuffer buf = new StringBuffer(); + + Matcher m = P_ENTITY.matcher(s); + while (m.find()) + { + final String match = m.group(1); + final int decimal = Integer.decode(match).intValue(); + m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal))); + } + m.appendTail(buf); + s = buf.toString(); + + buf = new StringBuffer(); + m = P_ENTITY_UNICODE.matcher(s); + while (m.find()) + { + final String match = m.group(1); + final int decimal = Integer.valueOf(match, 16).intValue(); + m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal))); + } + m.appendTail(buf); + s = buf.toString(); + + buf = new StringBuffer(); + m = P_ENCODE.matcher(s); + while (m.find()) + { + final String match = m.group(1); + final int decimal = Integer.valueOf(match, 16).intValue(); + m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal))); + } + m.appendTail(buf); + s = buf.toString(); + + s = validateEntities(s); + return s; + } + + private String validateEntities(final String s) + { + StringBuffer buf = new StringBuffer(); + + // validate entities throughout the string + Matcher m = P_VALID_ENTITIES.matcher(s); + while (m.find()) + { + // ([^&;]*) + final String one = m.group(1); + // (?=(;|&|$)) + final String two = m.group(2); + m.appendReplacement(buf, Matcher.quoteReplacement(checkEntity(one, two))); + } + m.appendTail(buf); + + return encodeQuotes(buf.toString()); + } + + private String encodeQuotes(final String s) + { + if (encodeQuotes) + { + StringBuffer buf = new StringBuffer(); + Matcher m = P_VALID_QUOTES.matcher(s); + while (m.find()) + { + // (>|^) + final String one = m.group(1); + // ([^<]+?) + final String two = m.group(2); + // (<|$) + final String three = m.group(3); + // 不替换双引号为",防止json格式无效 regexReplace(P_QUOTE, """, two) + m.appendReplacement(buf, Matcher.quoteReplacement(one + two + three)); + } + m.appendTail(buf); + return buf.toString(); + } + else + { + return s; + } + } + + private String checkEntity(final String preamble, final String term) + { + + return ";".equals(term) && isValidEntity(preamble) ? '&' + preamble : "&" + preamble; + } + + private boolean isValidEntity(final String entity) + { + return inArray(entity, vAllowedEntities); + } + + private static boolean inArray(final String s, final String[] array) + { + for (String item : array) + { + if (item != null && item.equals(s)) + { + return true; + } + } + return false; + } + + private boolean allowed(final String name) + { + return (vAllowed.isEmpty() || vAllowed.containsKey(name)) && !inArray(name, vDisallowed); + } + + private boolean allowedAttribute(final String name, final String paramName) + { + return allowed(name) && (vAllowed.isEmpty() || vAllowed.get(name).contains(paramName)); + } +} \ No newline at end of file diff --git a/zzyl-common/src/main/java/com/zzyl/common/utils/http/HttpHelper.java b/zzyl-common/src/main/java/com/zzyl/common/utils/http/HttpHelper.java new file mode 100644 index 0000000..fec355e --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/utils/http/HttpHelper.java @@ -0,0 +1,55 @@ +package com.zzyl.common.utils.http; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import javax.servlet.ServletRequest; +import org.apache.commons.lang3.exception.ExceptionUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * 通用http工具封装 + * + * @author ruoyi + */ +public class HttpHelper +{ + private static final Logger LOGGER = LoggerFactory.getLogger(HttpHelper.class); + + public static String getBodyString(ServletRequest request) + { + StringBuilder sb = new StringBuilder(); + BufferedReader reader = null; + try (InputStream inputStream = request.getInputStream()) + { + reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)); + String line = ""; + while ((line = reader.readLine()) != null) + { + sb.append(line); + } + } + catch (IOException e) + { + LOGGER.warn("getBodyString出现问题!"); + } + finally + { + if (reader != null) + { + try + { + reader.close(); + } + catch (IOException e) + { + LOGGER.error(ExceptionUtils.getMessage(e)); + } + } + } + return sb.toString(); + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/utils/http/HttpUtils.java b/zzyl-common/src/main/java/com/zzyl/common/utils/http/HttpUtils.java new file mode 100644 index 0000000..c0b709a --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/utils/http/HttpUtils.java @@ -0,0 +1,274 @@ +package com.zzyl.common.utils.http; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.net.ConnectException; +import java.net.SocketTimeoutException; +import java.net.URL; +import java.net.URLConnection; +import java.nio.charset.StandardCharsets; +import java.security.cert.X509Certificate; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.zzyl.common.constant.Constants; +import com.zzyl.common.utils.StringUtils; + +/** + * 通用http发送方法 + * + * @author ruoyi + */ +public class HttpUtils +{ + private static final Logger log = LoggerFactory.getLogger(HttpUtils.class); + + /** + * 向指定 URL 发送GET方法的请求 + * + * @param url 发送请求的 URL + * @return 所代表远程资源的响应结果 + */ + public static String sendGet(String url) + { + return sendGet(url, StringUtils.EMPTY); + } + + /** + * 向指定 URL 发送GET方法的请求 + * + * @param url 发送请求的 URL + * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 + * @return 所代表远程资源的响应结果 + */ + public static String sendGet(String url, String param) + { + return sendGet(url, param, Constants.UTF8); + } + + /** + * 向指定 URL 发送GET方法的请求 + * + * @param url 发送请求的 URL + * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 + * @param contentType 编码类型 + * @return 所代表远程资源的响应结果 + */ + public static String sendGet(String url, String param, String contentType) + { + StringBuilder result = new StringBuilder(); + BufferedReader in = null; + try + { + String urlNameString = StringUtils.isNotBlank(param) ? url + "?" + param : url; + log.info("sendGet - {}", urlNameString); + URL realUrl = new URL(urlNameString); + URLConnection connection = realUrl.openConnection(); + connection.setRequestProperty("accept", "*/*"); + connection.setRequestProperty("connection", "Keep-Alive"); + connection.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"); + connection.connect(); + in = new BufferedReader(new InputStreamReader(connection.getInputStream(), contentType)); + String line; + while ((line = in.readLine()) != null) + { + result.append(line); + } + log.info("recv - {}", result); + } + catch (ConnectException e) + { + log.error("调用HttpUtils.sendGet ConnectException, url=" + url + ",param=" + param, e); + } + catch (SocketTimeoutException e) + { + log.error("调用HttpUtils.sendGet SocketTimeoutException, url=" + url + ",param=" + param, e); + } + catch (IOException e) + { + log.error("调用HttpUtils.sendGet IOException, url=" + url + ",param=" + param, e); + } + catch (Exception e) + { + log.error("调用HttpsUtil.sendGet Exception, url=" + url + ",param=" + param, e); + } + finally + { + try + { + if (in != null) + { + in.close(); + } + } + catch (Exception ex) + { + log.error("调用in.close Exception, url=" + url + ",param=" + param, ex); + } + } + return result.toString(); + } + + /** + * 向指定 URL 发送POST方法的请求 + * + * @param url 发送请求的 URL + * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 + * @return 所代表远程资源的响应结果 + */ + public static String sendPost(String url, String param) + { + PrintWriter out = null; + BufferedReader in = null; + StringBuilder result = new StringBuilder(); + try + { + log.info("sendPost - {}", url); + URL realUrl = new URL(url); + URLConnection conn = realUrl.openConnection(); + conn.setRequestProperty("accept", "*/*"); + conn.setRequestProperty("connection", "Keep-Alive"); + conn.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"); + conn.setRequestProperty("Accept-Charset", "utf-8"); + conn.setRequestProperty("contentType", "utf-8"); + conn.setDoOutput(true); + conn.setDoInput(true); + out = new PrintWriter(conn.getOutputStream()); + out.print(param); + out.flush(); + in = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8)); + String line; + while ((line = in.readLine()) != null) + { + result.append(line); + } + log.info("recv - {}", result); + } + catch (ConnectException e) + { + log.error("调用HttpUtils.sendPost ConnectException, url=" + url + ",param=" + param, e); + } + catch (SocketTimeoutException e) + { + log.error("调用HttpUtils.sendPost SocketTimeoutException, url=" + url + ",param=" + param, e); + } + catch (IOException e) + { + log.error("调用HttpUtils.sendPost IOException, url=" + url + ",param=" + param, e); + } + catch (Exception e) + { + log.error("调用HttpsUtil.sendPost Exception, url=" + url + ",param=" + param, e); + } + finally + { + try + { + if (out != null) + { + out.close(); + } + if (in != null) + { + in.close(); + } + } + catch (IOException ex) + { + log.error("调用in.close Exception, url=" + url + ",param=" + param, ex); + } + } + return result.toString(); + } + + public static String sendSSLPost(String url, String param) + { + StringBuilder result = new StringBuilder(); + String urlNameString = url + "?" + param; + try + { + log.info("sendSSLPost - {}", urlNameString); + SSLContext sc = SSLContext.getInstance("SSL"); + sc.init(null, new TrustManager[] { new TrustAnyTrustManager() }, new java.security.SecureRandom()); + URL console = new URL(urlNameString); + HttpsURLConnection conn = (HttpsURLConnection) console.openConnection(); + conn.setRequestProperty("accept", "*/*"); + conn.setRequestProperty("connection", "Keep-Alive"); + conn.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"); + conn.setRequestProperty("Accept-Charset", "utf-8"); + conn.setRequestProperty("contentType", "utf-8"); + conn.setDoOutput(true); + conn.setDoInput(true); + + conn.setSSLSocketFactory(sc.getSocketFactory()); + conn.setHostnameVerifier(new TrustAnyHostnameVerifier()); + conn.connect(); + InputStream is = conn.getInputStream(); + BufferedReader br = new BufferedReader(new InputStreamReader(is)); + String ret = ""; + while ((ret = br.readLine()) != null) + { + if (ret != null && !"".equals(ret.trim())) + { + result.append(new String(ret.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8)); + } + } + log.info("recv - {}", result); + conn.disconnect(); + br.close(); + } + catch (ConnectException e) + { + log.error("调用HttpUtils.sendSSLPost ConnectException, url=" + url + ",param=" + param, e); + } + catch (SocketTimeoutException e) + { + log.error("调用HttpUtils.sendSSLPost SocketTimeoutException, url=" + url + ",param=" + param, e); + } + catch (IOException e) + { + log.error("调用HttpUtils.sendSSLPost IOException, url=" + url + ",param=" + param, e); + } + catch (Exception e) + { + log.error("调用HttpsUtil.sendSSLPost Exception, url=" + url + ",param=" + param, e); + } + return result.toString(); + } + + private static class TrustAnyTrustManager implements X509TrustManager + { + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType) + { + } + + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType) + { + } + + @Override + public X509Certificate[] getAcceptedIssuers() + { + return new X509Certificate[] {}; + } + } + + private static class TrustAnyHostnameVerifier implements HostnameVerifier + { + @Override + public boolean verify(String hostname, SSLSession session) + { + return true; + } + } +} \ No newline at end of file diff --git a/zzyl-common/src/main/java/com/zzyl/common/utils/ip/AddressUtils.java b/zzyl-common/src/main/java/com/zzyl/common/utils/ip/AddressUtils.java new file mode 100644 index 0000000..08568c9 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/utils/ip/AddressUtils.java @@ -0,0 +1,56 @@ +package com.zzyl.common.utils.ip; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.zzyl.common.config.RuoYiConfig; +import com.zzyl.common.constant.Constants; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.common.utils.http.HttpUtils; + +/** + * 获取地址类 + * + * @author ruoyi + */ +public class AddressUtils +{ + private static final Logger log = LoggerFactory.getLogger(AddressUtils.class); + + // IP地址查询 + public static final String IP_URL = "http://whois.pconline.com.cn/ipJson.jsp"; + + // 未知地址 + public static final String UNKNOWN = "XX XX"; + + public static String getRealAddressByIP(String ip) + { + // 内网不查询 + if (IpUtils.internalIp(ip)) + { + return "内网IP"; + } + if (RuoYiConfig.isAddressEnabled()) + { + try + { + String rspStr = HttpUtils.sendGet(IP_URL, "ip=" + ip + "&json=true", Constants.GBK); + if (StringUtils.isEmpty(rspStr)) + { + log.error("获取地理位置异常 {}", ip); + return UNKNOWN; + } + JSONObject obj = JSON.parseObject(rspStr); + String region = obj.getString("pro"); + String city = obj.getString("city"); + return String.format("%s %s", region, city); + } + catch (Exception e) + { + log.error("获取地理位置异常 {}", ip); + } + } + return UNKNOWN; + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/utils/ip/IpUtils.java b/zzyl-common/src/main/java/com/zzyl/common/utils/ip/IpUtils.java new file mode 100644 index 0000000..f903521 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/utils/ip/IpUtils.java @@ -0,0 +1,382 @@ +package com.zzyl.common.utils.ip; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import javax.servlet.http.HttpServletRequest; +import com.zzyl.common.utils.ServletUtils; +import com.zzyl.common.utils.StringUtils; + +/** + * 获取IP方法 + * + * @author ruoyi + */ +public class IpUtils +{ + public final static String REGX_0_255 = "(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)"; + // 匹配 ip + public final static String REGX_IP = "((" + REGX_0_255 + "\\.){3}" + REGX_0_255 + ")"; + public final static String REGX_IP_WILDCARD = "(((\\*\\.){3}\\*)|(" + REGX_0_255 + "(\\.\\*){3})|(" + REGX_0_255 + "\\." + REGX_0_255 + ")(\\.\\*){2}" + "|((" + REGX_0_255 + "\\.){3}\\*))"; + // 匹配网段 + public final static String REGX_IP_SEG = "(" + REGX_IP + "\\-" + REGX_IP + ")"; + + /** + * 获取客户端IP + * + * @return IP地址 + */ + public static String getIpAddr() + { + return getIpAddr(ServletUtils.getRequest()); + } + + /** + * 获取客户端IP + * + * @param request 请求对象 + * @return IP地址 + */ + public static String getIpAddr(HttpServletRequest request) + { + if (request == null) + { + return "unknown"; + } + String ip = request.getHeader("x-forwarded-for"); + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) + { + ip = request.getHeader("Proxy-Client-IP"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) + { + ip = request.getHeader("X-Forwarded-For"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) + { + ip = request.getHeader("WL-Proxy-Client-IP"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) + { + ip = request.getHeader("X-Real-IP"); + } + + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) + { + ip = request.getRemoteAddr(); + } + + return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : getMultistageReverseProxyIp(ip); + } + + /** + * 检查是否为内部IP地址 + * + * @param ip IP地址 + * @return 结果 + */ + public static boolean internalIp(String ip) + { + byte[] addr = textToNumericFormatV4(ip); + return internalIp(addr) || "127.0.0.1".equals(ip); + } + + /** + * 检查是否为内部IP地址 + * + * @param addr byte地址 + * @return 结果 + */ + private static boolean internalIp(byte[] addr) + { + if (StringUtils.isNull(addr) || addr.length < 2) + { + return true; + } + final byte b0 = addr[0]; + final byte b1 = addr[1]; + // 10.x.x.x/8 + final byte SECTION_1 = 0x0A; + // 172.16.x.x/12 + final byte SECTION_2 = (byte) 0xAC; + final byte SECTION_3 = (byte) 0x10; + final byte SECTION_4 = (byte) 0x1F; + // 192.168.x.x/16 + final byte SECTION_5 = (byte) 0xC0; + final byte SECTION_6 = (byte) 0xA8; + switch (b0) + { + case SECTION_1: + return true; + case SECTION_2: + if (b1 >= SECTION_3 && b1 <= SECTION_4) + { + return true; + } + case SECTION_5: + switch (b1) + { + case SECTION_6: + return true; + } + default: + return false; + } + } + + /** + * 将IPv4地址转换成字节 + * + * @param text IPv4地址 + * @return byte 字节 + */ + public static byte[] textToNumericFormatV4(String text) + { + if (text.length() == 0) + { + return null; + } + + byte[] bytes = new byte[4]; + String[] elements = text.split("\\.", -1); + try + { + long l; + int i; + switch (elements.length) + { + case 1: + l = Long.parseLong(elements[0]); + if ((l < 0L) || (l > 4294967295L)) + { + return null; + } + bytes[0] = (byte) (int) (l >> 24 & 0xFF); + bytes[1] = (byte) (int) ((l & 0xFFFFFF) >> 16 & 0xFF); + bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF); + bytes[3] = (byte) (int) (l & 0xFF); + break; + case 2: + l = Integer.parseInt(elements[0]); + if ((l < 0L) || (l > 255L)) + { + return null; + } + bytes[0] = (byte) (int) (l & 0xFF); + l = Integer.parseInt(elements[1]); + if ((l < 0L) || (l > 16777215L)) + { + return null; + } + bytes[1] = (byte) (int) (l >> 16 & 0xFF); + bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF); + bytes[3] = (byte) (int) (l & 0xFF); + break; + case 3: + for (i = 0; i < 2; ++i) + { + l = Integer.parseInt(elements[i]); + if ((l < 0L) || (l > 255L)) + { + return null; + } + bytes[i] = (byte) (int) (l & 0xFF); + } + l = Integer.parseInt(elements[2]); + if ((l < 0L) || (l > 65535L)) + { + return null; + } + bytes[2] = (byte) (int) (l >> 8 & 0xFF); + bytes[3] = (byte) (int) (l & 0xFF); + break; + case 4: + for (i = 0; i < 4; ++i) + { + l = Integer.parseInt(elements[i]); + if ((l < 0L) || (l > 255L)) + { + return null; + } + bytes[i] = (byte) (int) (l & 0xFF); + } + break; + default: + return null; + } + } + catch (NumberFormatException e) + { + return null; + } + return bytes; + } + + /** + * 获取IP地址 + * + * @return 本地IP地址 + */ + public static String getHostIp() + { + try + { + return InetAddress.getLocalHost().getHostAddress(); + } + catch (UnknownHostException e) + { + } + return "127.0.0.1"; + } + + /** + * 获取主机名 + * + * @return 本地主机名 + */ + public static String getHostName() + { + try + { + return InetAddress.getLocalHost().getHostName(); + } + catch (UnknownHostException e) + { + } + return "未知"; + } + + /** + * 从多级反向代理中获得第一个非unknown IP地址 + * + * @param ip 获得的IP地址 + * @return 第一个非unknown IP地址 + */ + public static String getMultistageReverseProxyIp(String ip) + { + // 多级反向代理检测 + if (ip != null && ip.indexOf(",") > 0) + { + final String[] ips = ip.trim().split(","); + for (String subIp : ips) + { + if (false == isUnknown(subIp)) + { + ip = subIp; + break; + } + } + } + return StringUtils.substring(ip, 0, 255); + } + + /** + * 检测给定字符串是否为未知,多用于检测HTTP请求相关 + * + * @param checkString 被检测的字符串 + * @return 是否未知 + */ + public static boolean isUnknown(String checkString) + { + return StringUtils.isBlank(checkString) || "unknown".equalsIgnoreCase(checkString); + } + + /** + * 是否为IP + */ + public static boolean isIP(String ip) + { + return StringUtils.isNotBlank(ip) && ip.matches(REGX_IP); + } + + /** + * 是否为IP,或 *为间隔的通配符地址 + */ + public static boolean isIpWildCard(String ip) + { + return StringUtils.isNotBlank(ip) && ip.matches(REGX_IP_WILDCARD); + } + + /** + * 检测参数是否在ip通配符里 + */ + public static boolean ipIsInWildCardNoCheck(String ipWildCard, String ip) + { + String[] s1 = ipWildCard.split("\\."); + String[] s2 = ip.split("\\."); + boolean isMatchedSeg = true; + for (int i = 0; i < s1.length && !"*".equals(s1[i]); i++) + { + if (!s1[i].equals(s2[i])) + { + isMatchedSeg = false; + break; + } + } + return isMatchedSeg; + } + + /** + * 是否为特定格式如:“10.10.10.1-10.10.10.99”的ip段字符串 + */ + public static boolean isIPSegment(String ipSeg) + { + return StringUtils.isNotBlank(ipSeg) && ipSeg.matches(REGX_IP_SEG); + } + + /** + * 判断ip是否在指定网段中 + */ + public static boolean ipIsInNetNoCheck(String iparea, String ip) + { + int idx = iparea.indexOf('-'); + String[] sips = iparea.substring(0, idx).split("\\."); + String[] sipe = iparea.substring(idx + 1).split("\\."); + String[] sipt = ip.split("\\."); + long ips = 0L, ipe = 0L, ipt = 0L; + for (int i = 0; i < 4; ++i) + { + ips = ips << 8 | Integer.parseInt(sips[i]); + ipe = ipe << 8 | Integer.parseInt(sipe[i]); + ipt = ipt << 8 | Integer.parseInt(sipt[i]); + } + if (ips > ipe) + { + long t = ips; + ips = ipe; + ipe = t; + } + return ips <= ipt && ipt <= ipe; + } + + /** + * 校验ip是否符合过滤串规则 + * + * @param filter 过滤IP列表,支持后缀'*'通配,支持网段如:`10.10.10.1-10.10.10.99` + * @param ip 校验IP地址 + * @return boolean 结果 + */ + public static boolean isMatchedIp(String filter, String ip) + { + if (StringUtils.isEmpty(filter) || StringUtils.isEmpty(ip)) + { + return false; + } + String[] ips = filter.split(";"); + for (String iStr : ips) + { + if (isIP(iStr) && iStr.equals(ip)) + { + return true; + } + else if (isIpWildCard(iStr) && ipIsInWildCardNoCheck(iStr, ip)) + { + return true; + } + else if (isIPSegment(iStr) && ipIsInNetNoCheck(iStr, ip)) + { + return true; + } + } + return false; + } +} \ No newline at end of file diff --git a/zzyl-common/src/main/java/com/zzyl/common/utils/poi/ExcelHandlerAdapter.java b/zzyl-common/src/main/java/com/zzyl/common/utils/poi/ExcelHandlerAdapter.java new file mode 100644 index 0000000..cd0eba8 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/utils/poi/ExcelHandlerAdapter.java @@ -0,0 +1,24 @@ +package com.zzyl.common.utils.poi; + +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.Workbook; + +/** + * Excel数据格式处理适配器 + * + * @author ruoyi + */ +public interface ExcelHandlerAdapter +{ + /** + * 格式化 + * + * @param value 单元格数据值 + * @param args excel注解args参数组 + * @param cell 单元格对象 + * @param wb 工作簿对象 + * + * @return 处理后的值 + */ + Object format(Object value, String[] args, Cell cell, Workbook wb); +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/utils/poi/ExcelUtil.java b/zzyl-common/src/main/java/com/zzyl/common/utils/poi/ExcelUtil.java new file mode 100644 index 0000000..8cc6820 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/utils/poi/ExcelUtil.java @@ -0,0 +1,1903 @@ +package com.zzyl.common.utils.poi; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.ParameterizedType; +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Comparator; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; +import javax.servlet.http.HttpServletResponse; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.RegExUtils; +import org.apache.commons.lang3.reflect.FieldUtils; +import org.apache.poi.hssf.usermodel.HSSFClientAnchor; +import org.apache.poi.hssf.usermodel.HSSFPicture; +import org.apache.poi.hssf.usermodel.HSSFPictureData; +import org.apache.poi.hssf.usermodel.HSSFShape; +import org.apache.poi.hssf.usermodel.HSSFSheet; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.ooxml.POIXMLDocumentPart; +import org.apache.poi.ss.usermodel.BorderStyle; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.CellType; +import org.apache.poi.ss.usermodel.ClientAnchor; +import org.apache.poi.ss.usermodel.DataFormat; +import org.apache.poi.ss.usermodel.DataValidation; +import org.apache.poi.ss.usermodel.DataValidationConstraint; +import org.apache.poi.ss.usermodel.DataValidationHelper; +import org.apache.poi.ss.usermodel.DateUtil; +import org.apache.poi.ss.usermodel.Drawing; +import org.apache.poi.ss.usermodel.FillPatternType; +import org.apache.poi.ss.usermodel.Font; +import org.apache.poi.ss.usermodel.HorizontalAlignment; +import org.apache.poi.ss.usermodel.IndexedColors; +import org.apache.poi.ss.usermodel.Name; +import org.apache.poi.ss.usermodel.PictureData; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.VerticalAlignment; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.ss.usermodel.WorkbookFactory; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.ss.util.CellRangeAddressList; +import org.apache.poi.util.IOUtils; +import org.apache.poi.xssf.streaming.SXSSFWorkbook; +import org.apache.poi.xssf.usermodel.XSSFClientAnchor; +import org.apache.poi.xssf.usermodel.XSSFDataValidation; +import org.apache.poi.xssf.usermodel.XSSFDrawing; +import org.apache.poi.xssf.usermodel.XSSFPicture; +import org.apache.poi.xssf.usermodel.XSSFShape; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTMarker; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.zzyl.common.annotation.Excel; +import com.zzyl.common.annotation.Excel.ColumnType; +import com.zzyl.common.annotation.Excel.Type; +import com.zzyl.common.annotation.Excels; +import com.zzyl.common.config.RuoYiConfig; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.core.text.Convert; +import com.zzyl.common.exception.UtilException; +import com.zzyl.common.utils.DateUtils; +import com.zzyl.common.utils.DictUtils; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.common.utils.file.FileTypeUtils; +import com.zzyl.common.utils.file.FileUtils; +import com.zzyl.common.utils.file.ImageUtils; +import com.zzyl.common.utils.reflect.ReflectUtils; + +/** + * Excel相关处理 + * + * @author ruoyi + */ +public class ExcelUtil +{ + private static final Logger log = LoggerFactory.getLogger(ExcelUtil.class); + + public static final String FORMULA_REGEX_STR = "=|-|\\+|@"; + + public static final String[] FORMULA_STR = { "=", "-", "+", "@" }; + + /** + * 用于dictType属性数据存储,避免重复查缓存 + */ + public Map sysDictMap = new HashMap(); + + /** + * Excel sheet最大行数,默认65536 + */ + public static final int sheetSize = 65536; + + /** + * 工作表名称 + */ + private String sheetName; + + /** + * 导出类型(EXPORT:导出数据;IMPORT:导入模板) + */ + private Type type; + + /** + * 工作薄对象 + */ + private Workbook wb; + + /** + * 工作表对象 + */ + private Sheet sheet; + + /** + * 样式列表 + */ + private Map styles; + + /** + * 导入导出数据列表 + */ + private List list; + + /** + * 注解列表 + */ + private List fields; + + /** + * 当前行号 + */ + private int rownum; + + /** + * 标题 + */ + private String title; + + /** + * 最大高度 + */ + private short maxHeight; + + /** + * 合并后最后行数 + */ + private int subMergedLastRowNum = 0; + + /** + * 合并后开始行数 + */ + private int subMergedFirstRowNum = 1; + + /** + * 对象的子列表方法 + */ + private Method subMethod; + + /** + * 对象的子列表属性 + */ + private List subFields; + + /** + * 统计列表 + */ + private Map statistics = new HashMap(); + + /** + * 数字格式 + */ + private static final DecimalFormat DOUBLE_FORMAT = new DecimalFormat("######0.00"); + + /** + * 实体对象 + */ + public Class clazz; + + /** + * 需要显示列属性 + */ + public String[] includeFields; + + /** + * 需要排除列属性 + */ + public String[] excludeFields; + + public ExcelUtil(Class clazz) + { + this.clazz = clazz; + } + + /** + * 仅在Excel中显示列属性 + * + * @param fields 列属性名 示例[单个"name"/多个"id","name"] + */ + public void showColumn(String... fields) + { + this.includeFields = fields; + } + + /** + * 隐藏Excel中列属性 + * + * @param fields 列属性名 示例[单个"name"/多个"id","name"] + */ + public void hideColumn(String... fields) + { + this.excludeFields = fields; + } + + public void init(List list, String sheetName, String title, Type type) + { + if (list == null) + { + list = new ArrayList(); + } + this.list = list; + this.sheetName = sheetName; + this.type = type; + this.title = title; + createExcelField(); + createWorkbook(); + createTitle(); + createSubHead(); + } + + /** + * 创建excel第一行标题 + */ + public void createTitle() + { + if (StringUtils.isNotEmpty(title)) + { + int titleLastCol = this.fields.size() - 1; + if (isSubList()) + { + titleLastCol = titleLastCol + subFields.size() - 1; + } + Row titleRow = sheet.createRow(rownum == 0 ? rownum++ : 0); + titleRow.setHeightInPoints(30); + Cell titleCell = titleRow.createCell(0); + titleCell.setCellStyle(styles.get("title")); + titleCell.setCellValue(title); + sheet.addMergedRegion(new CellRangeAddress(titleRow.getRowNum(), titleRow.getRowNum(), 0, titleLastCol)); + } + } + + /** + * 创建对象的子列表名称 + */ + public void createSubHead() + { + if (isSubList()) + { + Row subRow = sheet.createRow(rownum); + int column = 0; + int subFieldSize = subFields != null ? subFields.size() : 0; + for (Object[] objects : fields) + { + Field field = (Field) objects[0]; + Excel attr = (Excel) objects[1]; + if (Collection.class.isAssignableFrom(field.getType())) + { + Cell cell = subRow.createCell(column); + cell.setCellValue(attr.name()); + cell.setCellStyle(styles.get(StringUtils.format("header_{}_{}", attr.headerColor(), attr.headerBackgroundColor()))); + if (subFieldSize > 1) + { + CellRangeAddress cellAddress = new CellRangeAddress(rownum, rownum, column, column + subFieldSize - 1); + sheet.addMergedRegion(cellAddress); + } + column += subFieldSize; + } + else + { + Cell cell = subRow.createCell(column++); + cell.setCellValue(attr.name()); + cell.setCellStyle(styles.get(StringUtils.format("header_{}_{}", attr.headerColor(), attr.headerBackgroundColor()))); + } + } + rownum++; + } + } + + /** + * 对excel表单默认第一个索引名转换成list + * + * @param is 输入流 + * @return 转换后集合 + */ + public List importExcel(InputStream is) + { + return importExcel(is, 0); + } + + /** + * 对excel表单默认第一个索引名转换成list + * + * @param is 输入流 + * @param titleNum 标题占用行数 + * @return 转换后集合 + */ + public List importExcel(InputStream is, int titleNum) + { + List list = null; + try + { + list = importExcel(StringUtils.EMPTY, is, titleNum); + } + catch (Exception e) + { + log.error("导入Excel异常{}", e.getMessage()); + throw new UtilException(e.getMessage()); + } + finally + { + IOUtils.closeQuietly(is); + } + return list; + } + + /** + * 对excel表单指定表格索引名转换成list + * + * @param sheetName 表格索引名 + * @param titleNum 标题占用行数 + * @param is 输入流 + * @return 转换后集合 + */ + public List importExcel(String sheetName, InputStream is, int titleNum) throws Exception + { + this.type = Type.IMPORT; + this.wb = WorkbookFactory.create(is); + List list = new ArrayList(); + // 如果指定sheet名,则取指定sheet中的内容 否则默认指向第1个sheet + Sheet sheet = StringUtils.isNotEmpty(sheetName) ? wb.getSheet(sheetName) : wb.getSheetAt(0); + if (sheet == null) + { + throw new IOException("文件sheet不存在"); + } + boolean isXSSFWorkbook = !(wb instanceof HSSFWorkbook); + Map pictures; + if (isXSSFWorkbook) + { + pictures = getSheetPictures07((XSSFSheet) sheet, (XSSFWorkbook) wb); + } + else + { + pictures = getSheetPictures03((HSSFSheet) sheet, (HSSFWorkbook) wb); + } + // 获取最后一个非空行的行下标,比如总行数为n,则返回的为n-1 + int rows = sheet.getLastRowNum(); + if (rows > 0) + { + // 定义一个map用于存放excel列的序号和field. + Map cellMap = new HashMap(); + // 获取表头 + Row heard = sheet.getRow(titleNum); + for (int i = 0; i < heard.getPhysicalNumberOfCells(); i++) + { + Cell cell = heard.getCell(i); + if (StringUtils.isNotNull(cell)) + { + String value = this.getCellValue(heard, i).toString(); + cellMap.put(value, i); + } + else + { + cellMap.put(null, i); + } + } + // 有数据时才处理 得到类的所有field. + List fields = this.getFields(); + Map fieldsMap = new HashMap(); + for (Object[] objects : fields) + { + Excel attr = (Excel) objects[1]; + Integer column = cellMap.get(attr.name()); + if (column != null) + { + fieldsMap.put(column, objects); + } + } + for (int i = titleNum + 1; i <= rows; i++) + { + // 从第2行开始取数据,默认第一行是表头. + Row row = sheet.getRow(i); + // 判断当前行是否是空行 + if (isRowEmpty(row)) + { + continue; + } + T entity = null; + for (Map.Entry entry : fieldsMap.entrySet()) + { + Object val = this.getCellValue(row, entry.getKey()); + + // 如果不存在实例则新建. + entity = (entity == null ? clazz.getDeclaredConstructor().newInstance() : entity); + // 从map中得到对应列的field. + Field field = (Field) entry.getValue()[0]; + Excel attr = (Excel) entry.getValue()[1]; + // 取得类型,并根据对象类型设置值. + Class fieldType = field.getType(); + if (String.class == fieldType) + { + String s = Convert.toStr(val); + if (StringUtils.endsWith(s, ".0")) + { + val = StringUtils.substringBefore(s, ".0"); + } + else + { + String dateFormat = field.getAnnotation(Excel.class).dateFormat(); + if (StringUtils.isNotEmpty(dateFormat)) + { + val = parseDateToStr(dateFormat, val); + } + else + { + val = Convert.toStr(val); + } + } + } + else if ((Integer.TYPE == fieldType || Integer.class == fieldType) && StringUtils.isNumeric(Convert.toStr(val))) + { + val = Convert.toInt(val); + } + else if ((Long.TYPE == fieldType || Long.class == fieldType) && StringUtils.isNumeric(Convert.toStr(val))) + { + val = Convert.toLong(val); + } + else if (Double.TYPE == fieldType || Double.class == fieldType) + { + val = Convert.toDouble(val); + } + else if (Float.TYPE == fieldType || Float.class == fieldType) + { + val = Convert.toFloat(val); + } + else if (BigDecimal.class == fieldType) + { + val = Convert.toBigDecimal(val); + } + else if (Date.class == fieldType) + { + if (val instanceof String) + { + val = DateUtils.parseDate(val); + } + else if (val instanceof Double) + { + val = DateUtil.getJavaDate((Double) val); + } + } + else if (Boolean.TYPE == fieldType || Boolean.class == fieldType) + { + val = Convert.toBool(val, false); + } + if (StringUtils.isNotNull(fieldType)) + { + String propertyName = field.getName(); + if (StringUtils.isNotEmpty(attr.targetAttr())) + { + propertyName = field.getName() + "." + attr.targetAttr(); + } + if (StringUtils.isNotEmpty(attr.readConverterExp())) + { + val = reverseByExp(Convert.toStr(val), attr.readConverterExp(), attr.separator()); + } + else if (StringUtils.isNotEmpty(attr.dictType())) + { + if (!sysDictMap.containsKey(attr.dictType() + val)) + { + String dictValue = reverseDictByExp(Convert.toStr(val), attr.dictType(), attr.separator()); + sysDictMap.put(attr.dictType() + val, dictValue); + } + val = sysDictMap.get(attr.dictType() + val); + } + else if (!attr.handler().equals(ExcelHandlerAdapter.class)) + { + val = dataFormatHandlerAdapter(val, attr, null); + } + else if (ColumnType.IMAGE == attr.cellType() && StringUtils.isNotEmpty(pictures)) + { + PictureData image = pictures.get(row.getRowNum() + "_" + entry.getKey()); + if (image == null) + { + val = ""; + } + else + { + byte[] data = image.getData(); + val = FileUtils.writeImportBytes(data); + } + } + ReflectUtils.invokeSetter(entity, propertyName, val); + } + } + list.add(entity); + } + } + return list; + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param list 导出数据集合 + * @param sheetName 工作表的名称 + * @return 结果 + */ + public AjaxResult exportExcel(List list, String sheetName) + { + return exportExcel(list, sheetName, StringUtils.EMPTY); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param list 导出数据集合 + * @param sheetName 工作表的名称 + * @param title 标题 + * @return 结果 + */ + public AjaxResult exportExcel(List list, String sheetName, String title) + { + this.init(list, sheetName, title, Type.EXPORT); + return exportExcel(); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param response 返回数据 + * @param list 导出数据集合 + * @param sheetName 工作表的名称 + * @return 结果 + */ + public void exportExcel(HttpServletResponse response, List list, String sheetName) + { + exportExcel(response, list, sheetName, StringUtils.EMPTY); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param response 返回数据 + * @param list 导出数据集合 + * @param sheetName 工作表的名称 + * @param title 标题 + * @return 结果 + */ + public void exportExcel(HttpServletResponse response, List list, String sheetName, String title) + { + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setCharacterEncoding("utf-8"); + this.init(list, sheetName, title, Type.EXPORT); + exportExcel(response); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param sheetName 工作表的名称 + * @return 结果 + */ + public AjaxResult importTemplateExcel(String sheetName) + { + return importTemplateExcel(sheetName, StringUtils.EMPTY); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param sheetName 工作表的名称 + * @param title 标题 + * @return 结果 + */ + public AjaxResult importTemplateExcel(String sheetName, String title) + { + this.init(null, sheetName, title, Type.IMPORT); + return exportExcel(); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param sheetName 工作表的名称 + * @return 结果 + */ + public void importTemplateExcel(HttpServletResponse response, String sheetName) + { + importTemplateExcel(response, sheetName, StringUtils.EMPTY); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param sheetName 工作表的名称 + * @param title 标题 + * @return 结果 + */ + public void importTemplateExcel(HttpServletResponse response, String sheetName, String title) + { + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setCharacterEncoding("utf-8"); + this.init(null, sheetName, title, Type.IMPORT); + exportExcel(response); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @return 结果 + */ + public void exportExcel(HttpServletResponse response) + { + try + { + writeSheet(); + wb.write(response.getOutputStream()); + } + catch (Exception e) + { + log.error("导出Excel异常{}", e.getMessage()); + } + finally + { + IOUtils.closeQuietly(wb); + } + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @return 结果 + */ + public AjaxResult exportExcel() + { + OutputStream out = null; + try + { + writeSheet(); + String filename = encodingFilename(sheetName); + out = new FileOutputStream(getAbsoluteFile(filename)); + wb.write(out); + return AjaxResult.success(filename); + } + catch (Exception e) + { + log.error("导出Excel异常{}", e.getMessage()); + throw new UtilException("导出Excel失败,请联系网站管理员!"); + } + finally + { + IOUtils.closeQuietly(wb); + IOUtils.closeQuietly(out); + } + } + + /** + * 创建写入数据到Sheet + */ + public void writeSheet() + { + // 取出一共有多少个sheet. + int sheetNo = Math.max(1, (int) Math.ceil(list.size() * 1.0 / sheetSize)); + for (int index = 0; index < sheetNo; index++) + { + createSheet(sheetNo, index); + + // 产生一行 + Row row = sheet.createRow(rownum); + int column = 0; + // 写入各个字段的列头名称 + for (Object[] os : fields) + { + Field field = (Field) os[0]; + Excel excel = (Excel) os[1]; + if (Collection.class.isAssignableFrom(field.getType())) + { + for (Field subField : subFields) + { + Excel subExcel = subField.getAnnotation(Excel.class); + this.createHeadCell(subExcel, row, column++); + } + } + else + { + this.createHeadCell(excel, row, column++); + } + } + if (Type.EXPORT.equals(type)) + { + fillExcelData(index, row); + addStatisticsRow(); + } + } + } + + /** + * 填充excel数据 + * + * @param index 序号 + * @param row 单元格行 + */ + @SuppressWarnings("unchecked") + public void fillExcelData(int index, Row row) + { + int startNo = index * sheetSize; + int endNo = Math.min(startNo + sheetSize, list.size()); + // 从标题行后开始 + int currentRowNum = rownum + 1; + + for (int i = startNo; i < endNo; i++) + { + row = sheet.createRow(currentRowNum); + T vo = (T) list.get(i); + int column = 0; + int maxSubListSize = getCurrentMaxSubListSize(vo); + for (Object[] os : fields) + { + Field field = (Field) os[0]; + Excel excel = (Excel) os[1]; + if (Collection.class.isAssignableFrom(field.getType())) + { + try + { + Collection subList = (Collection) getTargetValue(vo, field, excel); + if (subList != null && !subList.isEmpty()) + { + int subIndex = 0; + for (Object subVo : subList) + { + Row subRow = sheet.getRow(currentRowNum + subIndex); + if (subRow == null) + { + subRow = sheet.createRow(currentRowNum + subIndex); + } + + int subColumn = column; + for (Field subField : subFields) + { + Excel subExcel = subField.getAnnotation(Excel.class); + addCell(subExcel, subRow, (T) subVo, subField, subColumn++); + } + subIndex++; + } + column += subFields.size(); + } + } + catch (Exception e) + { + log.error("填充集合数据失败", e); + } + } + else + { + // 创建单元格并设置值 + addCell(excel, row, vo, field, column); + if (maxSubListSize > 1 && excel.needMerge()) + { + sheet.addMergedRegion(new CellRangeAddress(currentRowNum, currentRowNum + maxSubListSize - 1, column, column)); + } + column++; + } + } + currentRowNum += maxSubListSize; + } + } + + /** + * 获取子列表最大数 + */ + private int getCurrentMaxSubListSize(T vo) + { + int maxSubListSize = 1; + for (Object[] os : fields) + { + Field field = (Field) os[0]; + if (Collection.class.isAssignableFrom(field.getType())) + { + try + { + Collection subList = (Collection) getTargetValue(vo, field, (Excel) os[1]); + if (subList != null && !subList.isEmpty()) + { + maxSubListSize = Math.max(maxSubListSize, subList.size()); + } + } + catch (Exception e) + { + log.error("获取集合大小失败", e); + } + } + } + return maxSubListSize; + } + + /** + * 创建表格样式 + * + * @param wb 工作薄对象 + * @return 样式列表 + */ + private Map createStyles(Workbook wb) + { + // 写入各条记录,每条记录对应excel表中的一行 + Map styles = new HashMap(); + CellStyle style = wb.createCellStyle(); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + Font titleFont = wb.createFont(); + titleFont.setFontName("Arial"); + titleFont.setFontHeightInPoints((short) 16); + titleFont.setBold(true); + style.setFont(titleFont); + DataFormat dataFormat = wb.createDataFormat(); + style.setDataFormat(dataFormat.getFormat("@")); + styles.put("title", style); + + style = wb.createCellStyle(); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + style.setBorderRight(BorderStyle.THIN); + style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderLeft(BorderStyle.THIN); + style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderTop(BorderStyle.THIN); + style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderBottom(BorderStyle.THIN); + style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + Font dataFont = wb.createFont(); + dataFont.setFontName("Arial"); + dataFont.setFontHeightInPoints((short) 10); + style.setFont(dataFont); + styles.put("data", style); + + style = wb.createCellStyle(); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + Font totalFont = wb.createFont(); + totalFont.setFontName("Arial"); + totalFont.setFontHeightInPoints((short) 10); + style.setFont(totalFont); + styles.put("total", style); + + styles.putAll(annotationHeaderStyles(wb, styles)); + + styles.putAll(annotationDataStyles(wb)); + + return styles; + } + + /** + * 根据Excel注解创建表格头样式 + * + * @param wb 工作薄对象 + * @return 自定义样式列表 + */ + private Map annotationHeaderStyles(Workbook wb, Map styles) + { + Map headerStyles = new HashMap(); + for (Object[] os : fields) + { + Excel excel = (Excel) os[1]; + String key = StringUtils.format("header_{}_{}", excel.headerColor(), excel.headerBackgroundColor()); + if (!headerStyles.containsKey(key)) + { + CellStyle style = wb.createCellStyle(); + style.cloneStyleFrom(styles.get("data")); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + style.setFillForegroundColor(excel.headerBackgroundColor().index); + style.setFillPattern(FillPatternType.SOLID_FOREGROUND); + Font headerFont = wb.createFont(); + headerFont.setFontName("Arial"); + headerFont.setFontHeightInPoints((short) 10); + headerFont.setBold(true); + headerFont.setColor(excel.headerColor().index); + style.setFont(headerFont); + // 设置表格头单元格文本形式 + DataFormat dataFormat = wb.createDataFormat(); + style.setDataFormat(dataFormat.getFormat("@")); + headerStyles.put(key, style); + } + } + return headerStyles; + } + + /** + * 根据Excel注解创建表格列样式 + * + * @param wb 工作薄对象 + * @return 自定义样式列表 + */ + private Map annotationDataStyles(Workbook wb) + { + Map styles = new HashMap(); + for (Object[] os : fields) + { + Field field = (Field) os[0]; + Excel excel = (Excel) os[1]; + if (Collection.class.isAssignableFrom(field.getType())) + { + ParameterizedType pt = (ParameterizedType) field.getGenericType(); + Class subClass = (Class) pt.getActualTypeArguments()[0]; + List subFields = FieldUtils.getFieldsListWithAnnotation(subClass, Excel.class); + for (Field subField : subFields) + { + Excel subExcel = subField.getAnnotation(Excel.class); + annotationDataStyles(styles, subField, subExcel); + } + } + else + { + annotationDataStyles(styles, field, excel); + } + } + return styles; + } + + /** + * 根据Excel注解创建表格列样式 + * + * @param styles 自定义样式列表 + * @param field 属性列信息 + * @param excel 注解信息 + */ + public void annotationDataStyles(Map styles, Field field, Excel excel) + { + String key = StringUtils.format("data_{}_{}_{}_{}_{}", excel.align(), excel.color(), excel.backgroundColor(), excel.cellType(), excel.wrapText()); + if (!styles.containsKey(key)) + { + CellStyle style = wb.createCellStyle(); + style.setAlignment(excel.align()); + style.setVerticalAlignment(VerticalAlignment.CENTER); + style.setBorderRight(BorderStyle.THIN); + style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderLeft(BorderStyle.THIN); + style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderTop(BorderStyle.THIN); + style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderBottom(BorderStyle.THIN); + style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setFillPattern(FillPatternType.SOLID_FOREGROUND); + style.setFillForegroundColor(excel.backgroundColor().getIndex()); + style.setWrapText(excel.wrapText()); + Font dataFont = wb.createFont(); + dataFont.setFontName("Arial"); + dataFont.setFontHeightInPoints((short) 10); + dataFont.setColor(excel.color().index); + style.setFont(dataFont); + if (ColumnType.TEXT == excel.cellType()) + { + DataFormat dataFormat = wb.createDataFormat(); + style.setDataFormat(dataFormat.getFormat("@")); + } + styles.put(key, style); + } + } + + /** + * 创建单元格 + */ + public Cell createHeadCell(Excel attr, Row row, int column) + { + // 创建列 + Cell cell = row.createCell(column); + // 写入列信息 + cell.setCellValue(attr.name()); + setDataValidation(attr, row, column); + cell.setCellStyle(styles.get(StringUtils.format("header_{}_{}", attr.headerColor(), attr.headerBackgroundColor()))); + if (isSubList()) + { + // 填充默认样式,防止合并单元格样式失效 + sheet.setDefaultColumnStyle(column, styles.get(StringUtils.format("data_{}_{}_{}_{}_{}", attr.align(), attr.color(), attr.backgroundColor(), attr.cellType(), attr.wrapText()))); + if (attr.needMerge()) + { + sheet.addMergedRegion(new CellRangeAddress(rownum - 1, rownum, column, column)); + } + } + return cell; + } + + /** + * 设置单元格信息 + * + * @param value 单元格值 + * @param attr 注解相关 + * @param cell 单元格信息 + */ + public void setCellVo(Object value, Excel attr, Cell cell) + { + if (ColumnType.STRING == attr.cellType() || ColumnType.TEXT == attr.cellType()) + { + String cellValue = Convert.toStr(value); + // 对于任何以表达式触发字符 =-+@开头的单元格,直接使用tab字符作为前缀,防止CSV注入。 + if (StringUtils.startsWithAny(cellValue, FORMULA_STR)) + { + cellValue = RegExUtils.replaceFirst(cellValue, FORMULA_REGEX_STR, "\t$0"); + } + if (value instanceof Collection && StringUtils.equals("[]", cellValue)) + { + cellValue = StringUtils.EMPTY; + } + cell.setCellValue(StringUtils.isNull(cellValue) ? attr.defaultValue() : cellValue + attr.suffix()); + } + else if (ColumnType.NUMERIC == attr.cellType()) + { + if (StringUtils.isNotNull(value)) + { + cell.setCellValue(StringUtils.contains(Convert.toStr(value), ".") ? Convert.toDouble(value) : Convert.toInt(value)); + } + } + else if (ColumnType.IMAGE == attr.cellType()) + { + ClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, (short) cell.getColumnIndex(), cell.getRow().getRowNum(), (short) (cell.getColumnIndex() + 1), cell.getRow().getRowNum() + 1); + String imagePath = Convert.toStr(value); + if (StringUtils.isNotEmpty(imagePath)) + { + byte[] data = ImageUtils.getImage(imagePath); + getDrawingPatriarch(cell.getSheet()).createPicture(anchor, + cell.getSheet().getWorkbook().addPicture(data, getImageType(data))); + } + } + } + + /** + * 获取画布 + */ + public static Drawing getDrawingPatriarch(Sheet sheet) + { + if (sheet.getDrawingPatriarch() == null) + { + sheet.createDrawingPatriarch(); + } + return sheet.getDrawingPatriarch(); + } + + /** + * 获取图片类型,设置图片插入类型 + */ + public int getImageType(byte[] value) + { + String type = FileTypeUtils.getFileExtendName(value); + if ("JPG".equalsIgnoreCase(type)) + { + return Workbook.PICTURE_TYPE_JPEG; + } + else if ("PNG".equalsIgnoreCase(type)) + { + return Workbook.PICTURE_TYPE_PNG; + } + return Workbook.PICTURE_TYPE_JPEG; + } + + /** + * 创建表格样式 + */ + public void setDataValidation(Excel attr, Row row, int column) + { + if (attr.name().indexOf("注:") >= 0) + { + sheet.setColumnWidth(column, 6000); + } + else + { + // 设置列宽 + sheet.setColumnWidth(column, (int) ((attr.width() + 0.72) * 256)); + } + if (StringUtils.isNotEmpty(attr.prompt()) || attr.combo().length > 0 || attr.comboReadDict()) + { + String[] comboArray = attr.combo(); + if (attr.comboReadDict()) + { + if (!sysDictMap.containsKey("combo_" + attr.dictType())) + { + String labels = DictUtils.getDictLabels(attr.dictType()); + sysDictMap.put("combo_" + attr.dictType(), labels); + } + String val = sysDictMap.get("combo_" + attr.dictType()); + comboArray = StringUtils.split(val, DictUtils.SEPARATOR); + } + if (comboArray.length > 15 || StringUtils.join(comboArray).length() > 255) + { + // 如果下拉数大于15或字符串长度大于255,则使用一个新sheet存储,避免生成的模板下拉值获取不到 + setXSSFValidationWithHidden(sheet, comboArray, attr.prompt(), 1, 100, column, column); + } + else + { + // 提示信息或只能选择不能输入的列内容. + setPromptOrValidation(sheet, comboArray, attr.prompt(), 1, 100, column, column); + } + } + } + + /** + * 添加单元格 + */ + public Cell addCell(Excel attr, Row row, T vo, Field field, int column) + { + Cell cell = null; + try + { + // 设置行高 + row.setHeight(maxHeight); + // 根据Excel中设置情况决定是否导出,有些情况需要保持为空,希望用户填写这一列. + if (attr.isExport()) + { + // 创建cell + cell = row.createCell(column); + if (isSubListValue(vo) && getListCellValue(vo).size() > 1 && attr.needMerge()) + { + if (subMergedLastRowNum >= subMergedFirstRowNum) + { + sheet.addMergedRegion(new CellRangeAddress(subMergedFirstRowNum, subMergedLastRowNum, column, column)); + } + } + cell.setCellStyle(styles.get(StringUtils.format("data_{}_{}_{}_{}_{}", attr.align(), attr.color(), attr.backgroundColor(), attr.cellType(), attr.wrapText()))); + + // 用于读取对象中的属性 + Object value = getTargetValue(vo, field, attr); + String dateFormat = attr.dateFormat(); + String readConverterExp = attr.readConverterExp(); + String separator = attr.separator(); + String dictType = attr.dictType(); + if (StringUtils.isNotEmpty(dateFormat) && StringUtils.isNotNull(value)) + { + cell.setCellValue(parseDateToStr(dateFormat, value)); + } + else if (StringUtils.isNotEmpty(readConverterExp) && StringUtils.isNotNull(value)) + { + cell.setCellValue(convertByExp(Convert.toStr(value), readConverterExp, separator)); + } + else if (StringUtils.isNotEmpty(dictType) && StringUtils.isNotNull(value)) + { + if (!sysDictMap.containsKey(dictType + value)) + { + String lable = convertDictByExp(Convert.toStr(value), dictType, separator); + sysDictMap.put(dictType + value, lable); + } + cell.setCellValue(sysDictMap.get(dictType + value)); + } + else if (value instanceof BigDecimal && -1 != attr.scale()) + { + cell.setCellValue((((BigDecimal) value).setScale(attr.scale(), attr.roundingMode())).doubleValue()); + } + else if (!attr.handler().equals(ExcelHandlerAdapter.class)) + { + cell.setCellValue(dataFormatHandlerAdapter(value, attr, cell)); + } + else + { + // 设置列类型 + setCellVo(value, attr, cell); + } + addStatisticsData(column, Convert.toStr(value), attr); + } + } + catch (Exception e) + { + log.error("导出Excel失败{}", e); + } + return cell; + } + + /** + * 设置 POI XSSFSheet 单元格提示或选择框 + * + * @param sheet 表单 + * @param textlist 下拉框显示的内容 + * @param promptContent 提示内容 + * @param firstRow 开始行 + * @param endRow 结束行 + * @param firstCol 开始列 + * @param endCol 结束列 + */ + public void setPromptOrValidation(Sheet sheet, String[] textlist, String promptContent, int firstRow, int endRow, + int firstCol, int endCol) + { + DataValidationHelper helper = sheet.getDataValidationHelper(); + DataValidationConstraint constraint = textlist.length > 0 ? helper.createExplicitListConstraint(textlist) : helper.createCustomConstraint("DD1"); + CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol); + DataValidation dataValidation = helper.createValidation(constraint, regions); + if (StringUtils.isNotEmpty(promptContent)) + { + // 如果设置了提示信息则鼠标放上去提示 + dataValidation.createPromptBox("", promptContent); + dataValidation.setShowPromptBox(true); + } + // 处理Excel兼容性问题 + if (dataValidation instanceof XSSFDataValidation) + { + dataValidation.setSuppressDropDownArrow(true); + dataValidation.setShowErrorBox(true); + } + else + { + dataValidation.setSuppressDropDownArrow(false); + } + sheet.addValidationData(dataValidation); + } + + /** + * 设置某些列的值只能输入预制的数据,显示下拉框(兼容超出一定数量的下拉框). + * + * @param sheet 要设置的sheet. + * @param textlist 下拉框显示的内容 + * @param promptContent 提示内容 + * @param firstRow 开始行 + * @param endRow 结束行 + * @param firstCol 开始列 + * @param endCol 结束列 + */ + public void setXSSFValidationWithHidden(Sheet sheet, String[] textlist, String promptContent, int firstRow, int endRow, int firstCol, int endCol) + { + String hideSheetName = "combo_" + firstCol + "_" + endCol; + // 用于存储 下拉菜单数据 + Sheet hideSheet = wb.createSheet(hideSheetName); + for (int i = 0; i < textlist.length; i++) + { + hideSheet.createRow(i).createCell(0).setCellValue(textlist[i]); + } + // 创建名称,可被其他单元格引用 + Name name = wb.createName(); + name.setNameName(hideSheetName + "_data"); + name.setRefersToFormula(hideSheetName + "!$A$1:$A$" + textlist.length); + DataValidationHelper helper = sheet.getDataValidationHelper(); + // 加载下拉列表内容 + DataValidationConstraint constraint = helper.createFormulaListConstraint(hideSheetName + "_data"); + // 设置数据有效性加载在哪个单元格上,四个参数分别是:起始行、终止行、起始列、终止列 + CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol); + // 数据有效性对象 + DataValidation dataValidation = helper.createValidation(constraint, regions); + if (StringUtils.isNotEmpty(promptContent)) + { + // 如果设置了提示信息则鼠标放上去提示 + dataValidation.createPromptBox("", promptContent); + dataValidation.setShowPromptBox(true); + } + // 处理Excel兼容性问题 + if (dataValidation instanceof XSSFDataValidation) + { + dataValidation.setSuppressDropDownArrow(true); + dataValidation.setShowErrorBox(true); + } + else + { + dataValidation.setSuppressDropDownArrow(false); + } + + sheet.addValidationData(dataValidation); + // 设置hiddenSheet隐藏 + wb.setSheetHidden(wb.getSheetIndex(hideSheet), true); + } + + /** + * 解析导出值 0=男,1=女,2=未知 + * + * @param propertyValue 参数值 + * @param converterExp 翻译注解 + * @param separator 分隔符 + * @return 解析后值 + */ + public static String convertByExp(String propertyValue, String converterExp, String separator) + { + StringBuilder propertyString = new StringBuilder(); + String[] convertSource = converterExp.split(","); + for (String item : convertSource) + { + String[] itemArray = item.split("="); + if (StringUtils.containsAny(propertyValue, separator)) + { + for (String value : propertyValue.split(separator)) + { + if (itemArray[0].equals(value)) + { + propertyString.append(itemArray[1] + separator); + break; + } + } + } + else + { + if (itemArray[0].equals(propertyValue)) + { + return itemArray[1]; + } + } + } + return StringUtils.stripEnd(propertyString.toString(), separator); + } + + /** + * 反向解析值 男=0,女=1,未知=2 + * + * @param propertyValue 参数值 + * @param converterExp 翻译注解 + * @param separator 分隔符 + * @return 解析后值 + */ + public static String reverseByExp(String propertyValue, String converterExp, String separator) + { + StringBuilder propertyString = new StringBuilder(); + String[] convertSource = converterExp.split(","); + for (String item : convertSource) + { + String[] itemArray = item.split("="); + if (StringUtils.containsAny(propertyValue, separator)) + { + for (String value : propertyValue.split(separator)) + { + if (itemArray[1].equals(value)) + { + propertyString.append(itemArray[0] + separator); + break; + } + } + } + else + { + if (itemArray[1].equals(propertyValue)) + { + return itemArray[0]; + } + } + } + return StringUtils.stripEnd(propertyString.toString(), separator); + } + + /** + * 解析字典值 + * + * @param dictValue 字典值 + * @param dictType 字典类型 + * @param separator 分隔符 + * @return 字典标签 + */ + public static String convertDictByExp(String dictValue, String dictType, String separator) + { + return DictUtils.getDictLabel(dictType, dictValue, separator); + } + + /** + * 反向解析值字典值 + * + * @param dictLabel 字典标签 + * @param dictType 字典类型 + * @param separator 分隔符 + * @return 字典值 + */ + public static String reverseDictByExp(String dictLabel, String dictType, String separator) + { + return DictUtils.getDictValue(dictType, dictLabel, separator); + } + + /** + * 数据处理器 + * + * @param value 数据值 + * @param excel 数据注解 + * @return + */ + public String dataFormatHandlerAdapter(Object value, Excel excel, Cell cell) + { + try + { + Object instance = excel.handler().getDeclaredConstructor().newInstance(); + Method formatMethod = excel.handler().getMethod("format", new Class[] { Object.class, String[].class, Cell.class, Workbook.class }); + value = formatMethod.invoke(instance, value, excel.args(), cell, this.wb); + } + catch (Exception e) + { + log.error("不能格式化数据 " + excel.handler(), e.getMessage()); + } + return Convert.toStr(value); + } + + /** + * 合计统计信息 + */ + private void addStatisticsData(Integer index, String text, Excel entity) + { + if (entity != null && entity.isStatistics()) + { + Double temp = 0D; + if (!statistics.containsKey(index)) + { + statistics.put(index, temp); + } + try + { + temp = Double.valueOf(text); + } + catch (NumberFormatException e) + { + } + statistics.put(index, statistics.get(index) + temp); + } + } + + /** + * 创建统计行 + */ + public void addStatisticsRow() + { + if (statistics.size() > 0) + { + Row row = sheet.createRow(sheet.getLastRowNum() + 1); + Set keys = statistics.keySet(); + Cell cell = row.createCell(0); + cell.setCellStyle(styles.get("total")); + cell.setCellValue("合计"); + + for (Integer key : keys) + { + cell = row.createCell(key); + cell.setCellStyle(styles.get("total")); + cell.setCellValue(DOUBLE_FORMAT.format(statistics.get(key))); + } + statistics.clear(); + } + } + + /** + * 编码文件名 + */ + public String encodingFilename(String filename) + { + filename = UUID.randomUUID() + "_" + filename + ".xlsx"; + return filename; + } + + /** + * 获取下载路径 + * + * @param filename 文件名称 + */ + public String getAbsoluteFile(String filename) + { + String downloadPath = RuoYiConfig.getDownloadPath() + filename; + File desc = new File(downloadPath); + if (!desc.getParentFile().exists()) + { + desc.getParentFile().mkdirs(); + } + return downloadPath; + } + + /** + * 获取bean中的属性值 + * + * @param vo 实体对象 + * @param field 字段 + * @param excel 注解 + * @return 最终的属性值 + * @throws Exception + */ + private Object getTargetValue(T vo, Field field, Excel excel) throws Exception + { + field.setAccessible(true); + Object o = field.get(vo); + if (StringUtils.isNotEmpty(excel.targetAttr())) + { + String target = excel.targetAttr(); + if (target.contains(".")) + { + String[] targets = target.split("[.]"); + for (String name : targets) + { + o = getValue(o, name); + } + } + else + { + o = getValue(o, target); + } + } + return o; + } + + /** + * 以类的属性的get方法方法形式获取值 + * + * @param o + * @param name + * @return value + * @throws Exception + */ + private Object getValue(Object o, String name) throws Exception + { + if (StringUtils.isNotNull(o) && StringUtils.isNotEmpty(name)) + { + Class clazz = o.getClass(); + Field field = clazz.getDeclaredField(name); + field.setAccessible(true); + o = field.get(o); + } + return o; + } + + /** + * 得到所有定义字段 + */ + private void createExcelField() + { + this.fields = getFields(); + this.fields = this.fields.stream().sorted(Comparator.comparing(objects -> ((Excel) objects[1]).sort())).collect(Collectors.toList()); + this.maxHeight = getRowHeight(); + } + + /** + * 获取字段注解信息 + */ + public List getFields() + { + List fields = new ArrayList(); + List tempFields = new ArrayList<>(); + tempFields.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredFields())); + tempFields.addAll(Arrays.asList(clazz.getDeclaredFields())); + if (StringUtils.isNotEmpty(includeFields)) + { + for (Field field : tempFields) + { + if (ArrayUtils.contains(this.includeFields, field.getName()) || field.isAnnotationPresent(Excels.class)) + { + addField(fields, field); + } + } + } + else if (StringUtils.isNotEmpty(excludeFields)) + { + for (Field field : tempFields) + { + if (!ArrayUtils.contains(this.excludeFields, field.getName())) + { + addField(fields, field); + } + } + } + else + { + for (Field field : tempFields) + { + addField(fields, field); + } + } + return fields; + } + + /** + * 添加字段信息 + */ + public void addField(List fields, Field field) + { + // 单注解 + if (field.isAnnotationPresent(Excel.class)) + { + Excel attr = field.getAnnotation(Excel.class); + if (attr != null && (attr.type() == Type.ALL || attr.type() == type)) + { + fields.add(new Object[] { field, attr }); + } + if (Collection.class.isAssignableFrom(field.getType())) + { + subMethod = getSubMethod(field.getName(), clazz); + ParameterizedType pt = (ParameterizedType) field.getGenericType(); + Class subClass = (Class) pt.getActualTypeArguments()[0]; + this.subFields = FieldUtils.getFieldsListWithAnnotation(subClass, Excel.class); + } + } + + // 多注解 + if (field.isAnnotationPresent(Excels.class)) + { + Excels attrs = field.getAnnotation(Excels.class); + Excel[] excels = attrs.value(); + for (Excel attr : excels) + { + if (StringUtils.isNotEmpty(includeFields)) + { + if (ArrayUtils.contains(this.includeFields, field.getName() + "." + attr.targetAttr()) + && (attr != null && (attr.type() == Type.ALL || attr.type() == type))) + { + fields.add(new Object[] { field, attr }); + } + } + else + { + if (!ArrayUtils.contains(this.excludeFields, field.getName() + "." + attr.targetAttr()) + && (attr != null && (attr.type() == Type.ALL || attr.type() == type))) + { + fields.add(new Object[] { field, attr }); + } + } + } + } + } + + /** + * 根据注解获取最大行高 + */ + public short getRowHeight() + { + double maxHeight = 0; + for (Object[] os : this.fields) + { + Excel excel = (Excel) os[1]; + maxHeight = Math.max(maxHeight, excel.height()); + } + return (short) (maxHeight * 20); + } + + /** + * 创建一个工作簿 + */ + public void createWorkbook() + { + this.wb = new SXSSFWorkbook(500); + this.sheet = wb.createSheet(); + wb.setSheetName(0, sheetName); + this.styles = createStyles(wb); + } + + /** + * 创建工作表 + * + * @param sheetNo sheet数量 + * @param index 序号 + */ + public void createSheet(int sheetNo, int index) + { + // 设置工作表的名称. + if (sheetNo > 1 && index > 0) + { + this.sheet = wb.createSheet(); + this.createTitle(); + wb.setSheetName(index, sheetName + index); + } + } + + /** + * 获取单元格值 + * + * @param row 获取的行 + * @param column 获取单元格列号 + * @return 单元格值 + */ + public Object getCellValue(Row row, int column) + { + if (row == null) + { + return row; + } + Object val = ""; + try + { + Cell cell = row.getCell(column); + if (StringUtils.isNotNull(cell)) + { + if (cell.getCellType() == CellType.NUMERIC || cell.getCellType() == CellType.FORMULA) + { + val = cell.getNumericCellValue(); + if (DateUtil.isCellDateFormatted(cell)) + { + // POI Excel 日期格式转换 + val = DateUtil.getJavaDate((Double) val); + } + else + { + if ((Double) val % 1 != 0) + { + val = new BigDecimal(val.toString()); + } + else + { + val = new DecimalFormat("0").format(val); + } + } + } + else if (cell.getCellType() == CellType.STRING) + { + val = cell.getStringCellValue(); + } + else if (cell.getCellType() == CellType.BOOLEAN) + { + val = cell.getBooleanCellValue(); + } + else if (cell.getCellType() == CellType.ERROR) + { + val = cell.getErrorCellValue(); + } + + } + } + catch (Exception e) + { + return val; + } + return val; + } + + /** + * 判断是否是空行 + * + * @param row 判断的行 + * @return + */ + private boolean isRowEmpty(Row row) + { + if (row == null) + { + return true; + } + for (int i = row.getFirstCellNum(); i < row.getLastCellNum(); i++) + { + Cell cell = row.getCell(i); + if (cell != null && cell.getCellType() != CellType.BLANK) + { + return false; + } + } + return true; + } + + /** + * 获取Excel2003图片 + * + * @param sheet 当前sheet对象 + * @param workbook 工作簿对象 + * @return Map key:图片单元格索引(1_1)String,value:图片流PictureData + */ + public static Map getSheetPictures03(HSSFSheet sheet, HSSFWorkbook workbook) + { + Map sheetIndexPicMap = new HashMap(); + List pictures = workbook.getAllPictures(); + if (!pictures.isEmpty()) + { + for (HSSFShape shape : sheet.getDrawingPatriarch().getChildren()) + { + HSSFClientAnchor anchor = (HSSFClientAnchor) shape.getAnchor(); + if (shape instanceof HSSFPicture) + { + HSSFPicture pic = (HSSFPicture) shape; + int pictureIndex = pic.getPictureIndex() - 1; + HSSFPictureData picData = pictures.get(pictureIndex); + String picIndex = anchor.getRow1() + "_" + anchor.getCol1(); + sheetIndexPicMap.put(picIndex, picData); + } + } + return sheetIndexPicMap; + } + else + { + return sheetIndexPicMap; + } + } + + /** + * 获取Excel2007图片 + * + * @param sheet 当前sheet对象 + * @param workbook 工作簿对象 + * @return Map key:图片单元格索引(1_1)String,value:图片流PictureData + */ + public static Map getSheetPictures07(XSSFSheet sheet, XSSFWorkbook workbook) + { + Map sheetIndexPicMap = new HashMap(); + for (POIXMLDocumentPart dr : sheet.getRelations()) + { + if (dr instanceof XSSFDrawing) + { + XSSFDrawing drawing = (XSSFDrawing) dr; + List shapes = drawing.getShapes(); + for (XSSFShape shape : shapes) + { + if (shape instanceof XSSFPicture) + { + XSSFPicture pic = (XSSFPicture) shape; + XSSFClientAnchor anchor = pic.getPreferredSize(); + CTMarker ctMarker = anchor.getFrom(); + String picIndex = ctMarker.getRow() + "_" + ctMarker.getCol(); + sheetIndexPicMap.put(picIndex, pic.getPictureData()); + } + } + } + } + return sheetIndexPicMap; + } + + /** + * 格式化不同类型的日期对象 + * + * @param dateFormat 日期格式 + * @param val 被格式化的日期对象 + * @return 格式化后的日期字符 + */ + public String parseDateToStr(String dateFormat, Object val) + { + if (val == null) + { + return ""; + } + String str; + if (val instanceof Date) + { + str = DateUtils.parseDateToStr(dateFormat, (Date) val); + } + else if (val instanceof LocalDateTime) + { + str = DateUtils.parseDateToStr(dateFormat, DateUtils.toDate((LocalDateTime) val)); + } + else if (val instanceof LocalDate) + { + str = DateUtils.parseDateToStr(dateFormat, DateUtils.toDate((LocalDate) val)); + } + else + { + str = val.toString(); + } + return str; + } + + /** + * 是否有对象的子列表 + */ + public boolean isSubList() + { + return StringUtils.isNotNull(subFields) && subFields.size() > 0; + } + + /** + * 是否有对象的子列表,集合不为空 + */ + public boolean isSubListValue(T vo) + { + return StringUtils.isNotNull(subFields) && subFields.size() > 0 && StringUtils.isNotNull(getListCellValue(vo)) && getListCellValue(vo).size() > 0; + } + + /** + * 获取集合的值 + */ + public Collection getListCellValue(Object obj) + { + Object value; + try + { + value = subMethod.invoke(obj, new Object[] {}); + } + catch (Exception e) + { + return new ArrayList(); + } + return (Collection) value; + } + + /** + * 获取对象的子列表方法 + * + * @param name 名称 + * @param pojoClass 类对象 + * @return 子列表方法 + */ + public Method getSubMethod(String name, Class pojoClass) + { + StringBuffer getMethodName = new StringBuffer("get"); + getMethodName.append(name.substring(0, 1).toUpperCase()); + getMethodName.append(name.substring(1)); + Method method = null; + try + { + method = pojoClass.getMethod(getMethodName.toString(), new Class[] {}); + } + catch (Exception e) + { + log.error("获取对象异常{}", e.getMessage()); + } + return method; + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/utils/reflect/ReflectUtils.java b/zzyl-common/src/main/java/com/zzyl/common/utils/reflect/ReflectUtils.java new file mode 100644 index 0000000..ad006da --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/utils/reflect/ReflectUtils.java @@ -0,0 +1,410 @@ +package com.zzyl.common.utils.reflect; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.Date; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.apache.poi.ss.usermodel.DateUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.zzyl.common.core.text.Convert; +import com.zzyl.common.utils.DateUtils; + +/** + * 反射工具类. 提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class, 被AOP过的真实类等工具函数. + * + * @author ruoyi + */ +@SuppressWarnings("rawtypes") +public class ReflectUtils +{ + private static final String SETTER_PREFIX = "set"; + + private static final String GETTER_PREFIX = "get"; + + private static final String CGLIB_CLASS_SEPARATOR = "$$"; + + private static Logger logger = LoggerFactory.getLogger(ReflectUtils.class); + + /** + * 调用Getter方法. + * 支持多级,如:对象名.对象名.方法 + */ + @SuppressWarnings("unchecked") + public static E invokeGetter(Object obj, String propertyName) + { + Object object = obj; + for (String name : StringUtils.split(propertyName, ".")) + { + String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(name); + object = invokeMethod(object, getterMethodName, new Class[] {}, new Object[] {}); + } + return (E) object; + } + + /** + * 调用Setter方法, 仅匹配方法名。 + * 支持多级,如:对象名.对象名.方法 + */ + public static void invokeSetter(Object obj, String propertyName, E value) + { + Object object = obj; + String[] names = StringUtils.split(propertyName, "."); + for (int i = 0; i < names.length; i++) + { + if (i < names.length - 1) + { + String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(names[i]); + object = invokeMethod(object, getterMethodName, new Class[] {}, new Object[] {}); + } + else + { + String setterMethodName = SETTER_PREFIX + StringUtils.capitalize(names[i]); + invokeMethodByName(object, setterMethodName, new Object[] { value }); + } + } + } + + /** + * 直接读取对象属性值, 无视private/protected修饰符, 不经过getter函数. + */ + @SuppressWarnings("unchecked") + public static E getFieldValue(final Object obj, final String fieldName) + { + Field field = getAccessibleField(obj, fieldName); + if (field == null) + { + logger.debug("在 [" + obj.getClass() + "] 中,没有找到 [" + fieldName + "] 字段 "); + return null; + } + E result = null; + try + { + result = (E) field.get(obj); + } + catch (IllegalAccessException e) + { + logger.error("不可能抛出的异常{}", e.getMessage()); + } + return result; + } + + /** + * 直接设置对象属性值, 无视private/protected修饰符, 不经过setter函数. + */ + public static void setFieldValue(final Object obj, final String fieldName, final E value) + { + Field field = getAccessibleField(obj, fieldName); + if (field == null) + { + // throw new IllegalArgumentException("在 [" + obj.getClass() + "] 中,没有找到 [" + fieldName + "] 字段 "); + logger.debug("在 [" + obj.getClass() + "] 中,没有找到 [" + fieldName + "] 字段 "); + return; + } + try + { + field.set(obj, value); + } + catch (IllegalAccessException e) + { + logger.error("不可能抛出的异常: {}", e.getMessage()); + } + } + + /** + * 直接调用对象方法, 无视private/protected修饰符. + * 用于一次性调用的情况,否则应使用getAccessibleMethod()函数获得Method后反复调用. + * 同时匹配方法名+参数类型, + */ + @SuppressWarnings("unchecked") + public static E invokeMethod(final Object obj, final String methodName, final Class[] parameterTypes, + final Object[] args) + { + if (obj == null || methodName == null) + { + return null; + } + Method method = getAccessibleMethod(obj, methodName, parameterTypes); + if (method == null) + { + logger.debug("在 [" + obj.getClass() + "] 中,没有找到 [" + methodName + "] 方法 "); + return null; + } + try + { + return (E) method.invoke(obj, args); + } + catch (Exception e) + { + String msg = "method: " + method + ", obj: " + obj + ", args: " + args + ""; + throw convertReflectionExceptionToUnchecked(msg, e); + } + } + + /** + * 直接调用对象方法, 无视private/protected修饰符, + * 用于一次性调用的情况,否则应使用getAccessibleMethodByName()函数获得Method后反复调用. + * 只匹配函数名,如果有多个同名函数调用第一个。 + */ + @SuppressWarnings("unchecked") + public static E invokeMethodByName(final Object obj, final String methodName, final Object[] args) + { + Method method = getAccessibleMethodByName(obj, methodName, args.length); + if (method == null) + { + // 如果为空不报错,直接返回空。 + logger.debug("在 [" + obj.getClass() + "] 中,没有找到 [" + methodName + "] 方法 "); + return null; + } + try + { + // 类型转换(将参数数据类型转换为目标方法参数类型) + Class[] cs = method.getParameterTypes(); + for (int i = 0; i < cs.length; i++) + { + if (args[i] != null && !args[i].getClass().equals(cs[i])) + { + if (cs[i] == String.class) + { + args[i] = Convert.toStr(args[i]); + if (StringUtils.endsWith((String) args[i], ".0")) + { + args[i] = StringUtils.substringBefore((String) args[i], ".0"); + } + } + else if (cs[i] == Integer.class) + { + args[i] = Convert.toInt(args[i]); + } + else if (cs[i] == Long.class) + { + args[i] = Convert.toLong(args[i]); + } + else if (cs[i] == Double.class) + { + args[i] = Convert.toDouble(args[i]); + } + else if (cs[i] == Float.class) + { + args[i] = Convert.toFloat(args[i]); + } + else if (cs[i] == Date.class) + { + if (args[i] instanceof String) + { + args[i] = DateUtils.parseDate(args[i]); + } + else + { + args[i] = DateUtil.getJavaDate((Double) args[i]); + } + } + else if (cs[i] == boolean.class || cs[i] == Boolean.class) + { + args[i] = Convert.toBool(args[i]); + } + } + } + return (E) method.invoke(obj, args); + } + catch (Exception e) + { + String msg = "method: " + method + ", obj: " + obj + ", args: " + args + ""; + throw convertReflectionExceptionToUnchecked(msg, e); + } + } + + /** + * 循环向上转型, 获取对象的DeclaredField, 并强制设置为可访问. + * 如向上转型到Object仍无法找到, 返回null. + */ + public static Field getAccessibleField(final Object obj, final String fieldName) + { + // 为空不报错。直接返回 null + if (obj == null) + { + return null; + } + Validate.notBlank(fieldName, "fieldName can't be blank"); + for (Class superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) + { + try + { + Field field = superClass.getDeclaredField(fieldName); + makeAccessible(field); + return field; + } + catch (NoSuchFieldException e) + { + continue; + } + } + return null; + } + + /** + * 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问. + * 如向上转型到Object仍无法找到, 返回null. + * 匹配函数名+参数类型。 + * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args) + */ + public static Method getAccessibleMethod(final Object obj, final String methodName, + final Class... parameterTypes) + { + // 为空不报错。直接返回 null + if (obj == null) + { + return null; + } + Validate.notBlank(methodName, "methodName can't be blank"); + for (Class searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) + { + try + { + Method method = searchType.getDeclaredMethod(methodName, parameterTypes); + makeAccessible(method); + return method; + } + catch (NoSuchMethodException e) + { + continue; + } + } + return null; + } + + /** + * 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问. + * 如向上转型到Object仍无法找到, 返回null. + * 只匹配函数名。 + * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args) + */ + public static Method getAccessibleMethodByName(final Object obj, final String methodName, int argsNum) + { + // 为空不报错。直接返回 null + if (obj == null) + { + return null; + } + Validate.notBlank(methodName, "methodName can't be blank"); + for (Class searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) + { + Method[] methods = searchType.getDeclaredMethods(); + for (Method method : methods) + { + if (method.getName().equals(methodName) && method.getParameterTypes().length == argsNum) + { + makeAccessible(method); + return method; + } + } + } + return null; + } + + /** + * 改变private/protected的方法为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。 + */ + public static void makeAccessible(Method method) + { + if ((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers())) + && !method.canAccess(null)) + { + method.setAccessible(true); + } + } + + /** + * 改变private/protected的成员变量为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。 + */ + public static void makeAccessible(Field field) + { + if ((!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers()) + || Modifier.isFinal(field.getModifiers())) && !field.canAccess(null)) + { + field.setAccessible(true); + } + } + + /** + * 通过反射, 获得Class定义中声明的泛型参数的类型, 注意泛型必须定义在父类处 + * 如无法找到, 返回Object.class. + */ + @SuppressWarnings("unchecked") + public static Class getClassGenricType(final Class clazz) + { + return getClassGenricType(clazz, 0); + } + + /** + * 通过反射, 获得Class定义中声明的父类的泛型参数的类型. + * 如无法找到, 返回Object.class. + */ + public static Class getClassGenricType(final Class clazz, final int index) + { + Type genType = clazz.getGenericSuperclass(); + + if (!(genType instanceof ParameterizedType)) + { + logger.debug(clazz.getSimpleName() + "'s superclass not ParameterizedType"); + return Object.class; + } + + Type[] params = ((ParameterizedType) genType).getActualTypeArguments(); + + if (index >= params.length || index < 0) + { + logger.debug("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: " + + params.length); + return Object.class; + } + if (!(params[index] instanceof Class)) + { + logger.debug(clazz.getSimpleName() + " not set the actual class on superclass generic parameter"); + return Object.class; + } + + return (Class) params[index]; + } + + public static Class getUserClass(Object instance) + { + if (instance == null) + { + throw new RuntimeException("Instance must not be null"); + } + Class clazz = instance.getClass(); + if (clazz != null && clazz.getName().contains(CGLIB_CLASS_SEPARATOR)) + { + Class superClass = clazz.getSuperclass(); + if (superClass != null && !Object.class.equals(superClass)) + { + return superClass; + } + } + return clazz; + + } + + /** + * 将反射时的checked exception转换为unchecked exception. + */ + public static RuntimeException convertReflectionExceptionToUnchecked(String msg, Exception e) + { + if (e instanceof IllegalAccessException || e instanceof IllegalArgumentException + || e instanceof NoSuchMethodException) + { + return new IllegalArgumentException(msg, e); + } + else if (e instanceof InvocationTargetException) + { + return new RuntimeException(msg, ((InvocationTargetException) e).getTargetException()); + } + return new RuntimeException(msg, e); + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/utils/sign/Base64.java b/zzyl-common/src/main/java/com/zzyl/common/utils/sign/Base64.java new file mode 100644 index 0000000..0f44d1e --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/utils/sign/Base64.java @@ -0,0 +1,295 @@ +package com.zzyl.common.utils.sign; + +/** + * Base64工具类 + * + * @author ruoyi + */ +public final class Base64 +{ + static private final int BASELENGTH = 128; + static private final int LOOKUPLENGTH = 64; + static private final int TWENTYFOURBITGROUP = 24; + static private final int EIGHTBIT = 8; + static private final int SIXTEENBIT = 16; + static private final int FOURBYTE = 4; + static private final int SIGN = -128; + static private final char PAD = '='; + static final private byte[] base64Alphabet = new byte[BASELENGTH]; + static final private char[] lookUpBase64Alphabet = new char[LOOKUPLENGTH]; + + static + { + for (int i = 0; i < BASELENGTH; ++i) + { + base64Alphabet[i] = -1; + } + for (int i = 'Z'; i >= 'A'; i--) + { + base64Alphabet[i] = (byte) (i - 'A'); + } + for (int i = 'z'; i >= 'a'; i--) + { + base64Alphabet[i] = (byte) (i - 'a' + 26); + } + + for (int i = '9'; i >= '0'; i--) + { + base64Alphabet[i] = (byte) (i - '0' + 52); + } + + base64Alphabet['+'] = 62; + base64Alphabet['/'] = 63; + + for (int i = 0; i <= 25; i++) + { + lookUpBase64Alphabet[i] = (char) ('A' + i); + } + + for (int i = 26, j = 0; i <= 51; i++, j++) + { + lookUpBase64Alphabet[i] = (char) ('a' + j); + } + + for (int i = 52, j = 0; i <= 61; i++, j++) + { + lookUpBase64Alphabet[i] = (char) ('0' + j); + } + lookUpBase64Alphabet[62] = (char) '+'; + lookUpBase64Alphabet[63] = (char) '/'; + } + + private static boolean isWhiteSpace(char octect) + { + return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9); + } + + private static boolean isPad(char octect) + { + return (octect == PAD); + } + + private static boolean isData(char octect) + { + return (octect < BASELENGTH && base64Alphabet[octect] != -1); + } + + /** + * Encodes hex octects into Base64 + * + * @param binaryData Array containing binaryData + * @return Encoded Base64 array + */ + public static String encode(byte[] binaryData) + { + if (binaryData == null) + { + return null; + } + + int lengthDataBits = binaryData.length * EIGHTBIT; + if (lengthDataBits == 0) + { + return ""; + } + + int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP; + int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP; + int numberQuartet = fewerThan24bits != 0 ? numberTriplets + 1 : numberTriplets; + char[] encodedData = null; + + encodedData = new char[numberQuartet * 4]; + + byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0; + + int encodedIndex = 0; + int dataIndex = 0; + + for (int i = 0; i < numberTriplets; i++) + { + b1 = binaryData[dataIndex++]; + b2 = binaryData[dataIndex++]; + b3 = binaryData[dataIndex++]; + + l = (byte) (b2 & 0x0f); + k = (byte) (b1 & 0x03); + + byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0); + byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0); + byte val3 = ((b3 & SIGN) == 0) ? (byte) (b3 >> 6) : (byte) ((b3) >> 6 ^ 0xfc); + + encodedData[encodedIndex++] = lookUpBase64Alphabet[val1]; + encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)]; + encodedData[encodedIndex++] = lookUpBase64Alphabet[(l << 2) | val3]; + encodedData[encodedIndex++] = lookUpBase64Alphabet[b3 & 0x3f]; + } + + // form integral number of 6-bit groups + if (fewerThan24bits == EIGHTBIT) + { + b1 = binaryData[dataIndex]; + k = (byte) (b1 & 0x03); + byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0); + encodedData[encodedIndex++] = lookUpBase64Alphabet[val1]; + encodedData[encodedIndex++] = lookUpBase64Alphabet[k << 4]; + encodedData[encodedIndex++] = PAD; + encodedData[encodedIndex++] = PAD; + } + else if (fewerThan24bits == SIXTEENBIT) + { + b1 = binaryData[dataIndex]; + b2 = binaryData[dataIndex + 1]; + l = (byte) (b2 & 0x0f); + k = (byte) (b1 & 0x03); + + byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0); + byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0); + + encodedData[encodedIndex++] = lookUpBase64Alphabet[val1]; + encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)]; + encodedData[encodedIndex++] = lookUpBase64Alphabet[l << 2]; + encodedData[encodedIndex++] = PAD; + } + return new String(encodedData); + } + + /** + * Decodes Base64 data into octects + * + * @param encoded string containing Base64 data + * @return Array containind decoded data. + */ + public static byte[] decode(String encoded) + { + if (encoded == null) + { + return null; + } + + char[] base64Data = encoded.toCharArray(); + // remove white spaces + int len = removeWhiteSpace(base64Data); + + if (len % FOURBYTE != 0) + { + // should be divisible by four + return null; + } + + int numberQuadruple = (len / FOURBYTE); + + if (numberQuadruple == 0) + { + return new byte[0]; + } + + byte[] decodedData = null; + byte b1 = 0, b2 = 0, b3 = 0, b4 = 0; + char d1 = 0, d2 = 0, d3 = 0, d4 = 0; + + int i = 0; + int encodedIndex = 0; + int dataIndex = 0; + decodedData = new byte[(numberQuadruple) * 3]; + + for (; i < numberQuadruple - 1; i++) + { + + if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++])) + || !isData((d3 = base64Data[dataIndex++])) || !isData((d4 = base64Data[dataIndex++]))) + { + return null; + } // if found "no data" just return null + + b1 = base64Alphabet[d1]; + b2 = base64Alphabet[d2]; + b3 = base64Alphabet[d3]; + b4 = base64Alphabet[d4]; + + decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4); + decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)); + decodedData[encodedIndex++] = (byte) (b3 << 6 | b4); + } + + if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++]))) + { + // if found "no data" just return null + return null; + } + + b1 = base64Alphabet[d1]; + b2 = base64Alphabet[d2]; + + d3 = base64Data[dataIndex++]; + d4 = base64Data[dataIndex++]; + if (!isData((d3)) || !isData((d4))) + {// Check if they are PAD characters + if (isPad(d3) && isPad(d4)) + { + // last 4 bits should be zero + if ((b2 & 0xf) != 0) + { + return null; + } + byte[] tmp = new byte[i * 3 + 1]; + System.arraycopy(decodedData, 0, tmp, 0, i * 3); + tmp[encodedIndex] = (byte) (b1 << 2 | b2 >> 4); + return tmp; + } + else if (!isPad(d3) && isPad(d4)) + { + b3 = base64Alphabet[d3]; + // last 2 bits should be zero + if ((b3 & 0x3) != 0) + { + return null; + } + byte[] tmp = new byte[i * 3 + 2]; + System.arraycopy(decodedData, 0, tmp, 0, i * 3); + tmp[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4); + tmp[encodedIndex] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)); + return tmp; + } + else + { + return null; + } + } + else + { // No PAD e.g 3cQl + b3 = base64Alphabet[d3]; + b4 = base64Alphabet[d4]; + decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4); + decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)); + decodedData[encodedIndex++] = (byte) (b3 << 6 | b4); + + } + return decodedData; + } + + /** + * remove WhiteSpace from MIME containing encoded Base64 data. + * + * @param data the byte array of base64 data (with WS) + * @return the new length + */ + private static int removeWhiteSpace(char[] data) + { + if (data == null) + { + return 0; + } + + // count characters that's not whitespace + int newSize = 0; + int len = data.length; + for (int i = 0; i < len; i++) + { + if (!isWhiteSpace(data[i])) + { + data[newSize++] = data[i]; + } + } + return newSize; + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/utils/sign/Md5Utils.java b/zzyl-common/src/main/java/com/zzyl/common/utils/sign/Md5Utils.java new file mode 100644 index 0000000..13e94d7 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/utils/sign/Md5Utils.java @@ -0,0 +1,67 @@ +package com.zzyl.common.utils.sign; + +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Md5加密方法 + * + * @author ruoyi + */ +public class Md5Utils +{ + private static final Logger log = LoggerFactory.getLogger(Md5Utils.class); + + private static byte[] md5(String s) + { + MessageDigest algorithm; + try + { + algorithm = MessageDigest.getInstance("MD5"); + algorithm.reset(); + algorithm.update(s.getBytes("UTF-8")); + byte[] messageDigest = algorithm.digest(); + return messageDigest; + } + catch (Exception e) + { + log.error("MD5 Error...", e); + } + return null; + } + + private static final String toHex(byte[] hash) + { + if (hash == null) + { + return null; + } + StringBuffer buf = new StringBuffer(hash.length * 2); + int i; + + for (i = 0; i < hash.length; i++) + { + if ((hash[i] & 0xff) < 0x10) + { + buf.append("0"); + } + buf.append(Long.toString(hash[i] & 0xff, 16)); + } + return buf.toString(); + } + + public static String hash(String s) + { + try + { + return new String(toHex(md5(s)).getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8); + } + catch (Exception e) + { + log.error("not supported charset...{}", e); + return s; + } + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/utils/spring/SpringUtils.java b/zzyl-common/src/main/java/com/zzyl/common/utils/spring/SpringUtils.java new file mode 100644 index 0000000..28da56c --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/utils/spring/SpringUtils.java @@ -0,0 +1,158 @@ +package com.zzyl.common.utils.spring; + +import org.springframework.aop.framework.AopContext; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.beans.factory.config.BeanFactoryPostProcessor; +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.stereotype.Component; +import com.zzyl.common.utils.StringUtils; + +/** + * spring工具类 方便在非spring管理环境中获取bean + * + * @author ruoyi + */ +@Component +public final class SpringUtils implements BeanFactoryPostProcessor, ApplicationContextAware +{ + /** Spring应用上下文环境 */ + private static ConfigurableListableBeanFactory beanFactory; + + private static ApplicationContext applicationContext; + + @Override + public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException + { + SpringUtils.beanFactory = beanFactory; + } + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException + { + SpringUtils.applicationContext = applicationContext; + } + + /** + * 获取对象 + * + * @param name + * @return Object 一个以所给名字注册的bean的实例 + * @throws org.springframework.beans.BeansException + * + */ + @SuppressWarnings("unchecked") + public static T getBean(String name) throws BeansException + { + return (T) beanFactory.getBean(name); + } + + /** + * 获取类型为requiredType的对象 + * + * @param clz + * @return + * @throws org.springframework.beans.BeansException + * + */ + public static T getBean(Class clz) throws BeansException + { + T result = (T) beanFactory.getBean(clz); + return result; + } + + /** + * 如果BeanFactory包含一个与所给名称匹配的bean定义,则返回true + * + * @param name + * @return boolean + */ + public static boolean containsBean(String name) + { + return beanFactory.containsBean(name); + } + + /** + * 判断以给定名字注册的bean定义是一个singleton还是一个prototype。 如果与给定名字相应的bean定义没有被找到,将会抛出一个异常(NoSuchBeanDefinitionException) + * + * @param name + * @return boolean + * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException + * + */ + public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException + { + return beanFactory.isSingleton(name); + } + + /** + * @param name + * @return Class 注册对象的类型 + * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException + * + */ + public static Class getType(String name) throws NoSuchBeanDefinitionException + { + return beanFactory.getType(name); + } + + /** + * 如果给定的bean名字在bean定义中有别名,则返回这些别名 + * + * @param name + * @return + * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException + * + */ + public static String[] getAliases(String name) throws NoSuchBeanDefinitionException + { + return beanFactory.getAliases(name); + } + + /** + * 获取aop代理对象 + * + * @param invoker + * @return + */ + @SuppressWarnings("unchecked") + public static T getAopProxy(T invoker) + { + return (T) AopContext.currentProxy(); + } + + /** + * 获取当前的环境配置,无配置返回null + * + * @return 当前的环境配置 + */ + public static String[] getActiveProfiles() + { + return applicationContext.getEnvironment().getActiveProfiles(); + } + + /** + * 获取当前的环境配置,当有多个环境配置时,只获取第一个 + * + * @return 当前的环境配置 + */ + public static String getActiveProfile() + { + final String[] activeProfiles = getActiveProfiles(); + return StringUtils.isNotEmpty(activeProfiles) ? activeProfiles[0] : null; + } + + /** + * 获取配置文件中的值 + * + * @param key 配置文件的key + * @return 当前的配置文件的值 + * + */ + public static String getRequiredProperty(String key) + { + return applicationContext.getEnvironment().getRequiredProperty(key); + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/utils/sql/SqlUtil.java b/zzyl-common/src/main/java/com/zzyl/common/utils/sql/SqlUtil.java new file mode 100644 index 0000000..c385bb1 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/utils/sql/SqlUtil.java @@ -0,0 +1,70 @@ +package com.zzyl.common.utils.sql; + +import com.zzyl.common.exception.UtilException; +import com.zzyl.common.utils.StringUtils; + +/** + * sql操作工具类 + * + * @author ruoyi + */ +public class SqlUtil +{ + /** + * 定义常用的 sql关键字 + */ + public static String SQL_REGEX = "\u000B|and |extractvalue|updatexml|sleep|exec |insert |select |delete |update |drop |count |chr |mid |master |truncate |char |declare |or |union |like |+|/*|user()"; + + /** + * 仅支持字母、数字、下划线、空格、逗号、小数点(支持多个字段排序) + */ + public static String SQL_PATTERN = "[a-zA-Z0-9_\\ \\,\\.]+"; + + /** + * 限制orderBy最大长度 + */ + private static final int ORDER_BY_MAX_LENGTH = 500; + + /** + * 检查字符,防止注入绕过 + */ + public static String escapeOrderBySql(String value) + { + if (StringUtils.isNotEmpty(value) && !isValidOrderBySql(value)) + { + throw new UtilException("参数不符合规范,不能进行查询"); + } + if (StringUtils.length(value) > ORDER_BY_MAX_LENGTH) + { + throw new UtilException("参数已超过最大限制,不能进行查询"); + } + return value; + } + + /** + * 验证 order by 语法是否符合规范 + */ + public static boolean isValidOrderBySql(String value) + { + return value.matches(SQL_PATTERN); + } + + /** + * SQL关键字检查 + */ + public static void filterKeyword(String value) + { + if (StringUtils.isEmpty(value)) + { + return; + } + String[] sqlKeywords = StringUtils.split(SQL_REGEX, "\\|"); + for (String sqlKeyword : sqlKeywords) + { + if (StringUtils.indexOfIgnoreCase(value, sqlKeyword) > -1) + { + throw new UtilException("参数存在SQL注入风险"); + } + } + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/utils/uuid/IdUtils.java b/zzyl-common/src/main/java/com/zzyl/common/utils/uuid/IdUtils.java new file mode 100644 index 0000000..ad82728 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/utils/uuid/IdUtils.java @@ -0,0 +1,49 @@ +package com.zzyl.common.utils.uuid; + +/** + * ID生成器工具类 + * + * @author ruoyi + */ +public class IdUtils +{ + /** + * 获取随机UUID + * + * @return 随机UUID + */ + public static String randomUUID() + { + return UUID.randomUUID().toString(); + } + + /** + * 简化的UUID,去掉了横线 + * + * @return 简化的UUID,去掉了横线 + */ + public static String simpleUUID() + { + return UUID.randomUUID().toString(true); + } + + /** + * 获取随机UUID,使用性能更好的ThreadLocalRandom生成UUID + * + * @return 随机UUID + */ + public static String fastUUID() + { + return UUID.fastUUID().toString(); + } + + /** + * 简化的UUID,去掉了横线,使用性能更好的ThreadLocalRandom生成UUID + * + * @return 简化的UUID,去掉了横线 + */ + public static String fastSimpleUUID() + { + return UUID.fastUUID().toString(true); + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/utils/uuid/Seq.java b/zzyl-common/src/main/java/com/zzyl/common/utils/uuid/Seq.java new file mode 100644 index 0000000..cb23f98 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/utils/uuid/Seq.java @@ -0,0 +1,86 @@ +package com.zzyl.common.utils.uuid; + +import java.util.concurrent.atomic.AtomicInteger; +import com.zzyl.common.utils.DateUtils; +import com.zzyl.common.utils.StringUtils; + +/** + * @author ruoyi 序列生成类 + */ +public class Seq +{ + // 通用序列类型 + public static final String commSeqType = "COMMON"; + + // 上传序列类型 + public static final String uploadSeqType = "UPLOAD"; + + // 通用接口序列数 + private static AtomicInteger commSeq = new AtomicInteger(1); + + // 上传接口序列数 + private static AtomicInteger uploadSeq = new AtomicInteger(1); + + // 机器标识 + private static final String machineCode = "A"; + + /** + * 获取通用序列号 + * + * @return 序列值 + */ + public static String getId() + { + return getId(commSeqType); + } + + /** + * 默认16位序列号 yyMMddHHmmss + 一位机器标识 + 3长度循环递增字符串 + * + * @return 序列值 + */ + public static String getId(String type) + { + AtomicInteger atomicInt = commSeq; + if (uploadSeqType.equals(type)) + { + atomicInt = uploadSeq; + } + return getId(atomicInt, 3); + } + + /** + * 通用接口序列号 yyMMddHHmmss + 一位机器标识 + length长度循环递增字符串 + * + * @param atomicInt 序列数 + * @param length 数值长度 + * @return 序列值 + */ + public static String getId(AtomicInteger atomicInt, int length) + { + String result = DateUtils.dateTimeNow(); + result += machineCode; + result += getSeq(atomicInt, length); + return result; + } + + /** + * 序列循环递增字符串[1, 10 的 (length)幂次方), 用0左补齐length位数 + * + * @return 序列值 + */ + private synchronized static String getSeq(AtomicInteger atomicInt, int length) + { + // 先取值再+1 + int value = atomicInt.getAndIncrement(); + + // 如果更新后值>=10 的 (length)幂次方则重置为1 + int maxSeq = (int) Math.pow(10, length); + if (atomicInt.get() >= maxSeq) + { + atomicInt.set(1); + } + // 转字符串,用0左补齐 + return StringUtils.padl(value, length); + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/utils/uuid/UUID.java b/zzyl-common/src/main/java/com/zzyl/common/utils/uuid/UUID.java new file mode 100644 index 0000000..90556a3 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/utils/uuid/UUID.java @@ -0,0 +1,490 @@ +package com.zzyl.common.utils.uuid; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; +import com.zzyl.common.exception.UtilException; + +/** + * 提供通用唯一识别码(universally unique identifier)(UUID)实现 + * + * @author ruoyi + */ +public final class UUID implements java.io.Serializable, Comparable +{ + private static final long serialVersionUID = -1185015143654744140L; + + /** + * SecureRandom 的单例 + * + */ + private static class Holder + { + static final SecureRandom numberGenerator = getSecureRandom(); + } + + /** 此UUID的最高64有效位 */ + private final long mostSigBits; + + /** 此UUID的最低64有效位 */ + private final long leastSigBits; + + /** + * 私有构造 + * + * @param data 数据 + */ + private UUID(byte[] data) + { + long msb = 0; + long lsb = 0; + assert data.length == 16 : "data must be 16 bytes in length"; + for (int i = 0; i < 8; i++) + { + msb = (msb << 8) | (data[i] & 0xff); + } + for (int i = 8; i < 16; i++) + { + lsb = (lsb << 8) | (data[i] & 0xff); + } + this.mostSigBits = msb; + this.leastSigBits = lsb; + } + + /** + * 使用指定的数据构造新的 UUID。 + * + * @param mostSigBits 用于 {@code UUID} 的最高有效 64 位 + * @param leastSigBits 用于 {@code UUID} 的最低有效 64 位 + */ + public UUID(long mostSigBits, long leastSigBits) + { + this.mostSigBits = mostSigBits; + this.leastSigBits = leastSigBits; + } + + /** + * 获取类型 4(伪随机生成的)UUID 的静态工厂。 + * + * @return 随机生成的 {@code UUID} + */ + public static UUID fastUUID() + { + return randomUUID(false); + } + + /** + * 获取类型 4(伪随机生成的)UUID 的静态工厂。 使用加密的强伪随机数生成器生成该 UUID。 + * + * @return 随机生成的 {@code UUID} + */ + public static UUID randomUUID() + { + return randomUUID(true); + } + + /** + * 获取类型 4(伪随机生成的)UUID 的静态工厂。 使用加密的强伪随机数生成器生成该 UUID。 + * + * @param isSecure 是否使用{@link SecureRandom}如果是可以获得更安全的随机码,否则可以得到更好的性能 + * @return 随机生成的 {@code UUID} + */ + public static UUID randomUUID(boolean isSecure) + { + final Random ng = isSecure ? Holder.numberGenerator : getRandom(); + + byte[] randomBytes = new byte[16]; + ng.nextBytes(randomBytes); + /* clear version */ + randomBytes[6] &= 0x0f; + /* set to version 4 */ + randomBytes[6] |= 0x40; + /* clear variant */ + randomBytes[8] &= 0x3f; + /* set to IETF variant */ + randomBytes[8] |= 0x80; + return new UUID(randomBytes); + } + + /** + * 根据指定的字节数组获取类型 3(基于名称的)UUID 的静态工厂。 + * + * @param name 用于构造 UUID 的字节数组。 + * + * @return 根据指定数组生成的 {@code UUID} + */ + public static UUID nameUUIDFromBytes(byte[] name) + { + MessageDigest md; + try + { + md = MessageDigest.getInstance("MD5"); + } + catch (NoSuchAlgorithmException nsae) + { + throw new InternalError("MD5 not supported"); + } + byte[] md5Bytes = md.digest(name); + /* clear version */ + md5Bytes[6] &= 0x0f; + /* set to version 3 */ + md5Bytes[6] |= 0x30; + /* clear variant */ + md5Bytes[8] &= 0x3f; + /* set to IETF variant */ + md5Bytes[8] |= 0x80; + return new UUID(md5Bytes); + } + + /** + * 根据 {@link #toString()} 方法中描述的字符串标准表示形式创建{@code UUID}。 + * + * @param name 指定 {@code UUID} 字符串 + * @return 具有指定值的 {@code UUID} + * @throws IllegalArgumentException 如果 name 与 {@link #toString} 中描述的字符串表示形式不符抛出此异常 + * + */ + public static UUID fromString(String name) + { + String[] components = name.split("-"); + if (components.length != 5) + { + throw new IllegalArgumentException("Invalid UUID string: " + name); + } + for (int i = 0; i < 5; i++) + { + components[i] = "0x" + components[i]; + } + + long mostSigBits = Long.decode(components[0]).longValue(); + mostSigBits <<= 16; + mostSigBits |= Long.decode(components[1]).longValue(); + mostSigBits <<= 16; + mostSigBits |= Long.decode(components[2]).longValue(); + + long leastSigBits = Long.decode(components[3]).longValue(); + leastSigBits <<= 48; + leastSigBits |= Long.decode(components[4]).longValue(); + + return new UUID(mostSigBits, leastSigBits); + } + + /** + * 返回此 UUID 的 128 位值中的最低有效 64 位。 + * + * @return 此 UUID 的 128 位值中的最低有效 64 位。 + */ + public long getLeastSignificantBits() + { + return leastSigBits; + } + + /** + * 返回此 UUID 的 128 位值中的最高有效 64 位。 + * + * @return 此 UUID 的 128 位值中最高有效 64 位。 + */ + public long getMostSignificantBits() + { + return mostSigBits; + } + + /** + * 与此 {@code UUID} 相关联的版本号. 版本号描述此 {@code UUID} 是如何生成的。 + *

+ * 版本号具有以下含意: + *

    + *
  • 1 基于时间的 UUID + *
  • 2 DCE 安全 UUID + *
  • 3 基于名称的 UUID + *
  • 4 随机生成的 UUID + *
+ * + * @return 此 {@code UUID} 的版本号 + */ + public int version() + { + // Version is bits masked by 0x000000000000F000 in MS long + return (int) ((mostSigBits >> 12) & 0x0f); + } + + /** + * 与此 {@code UUID} 相关联的变体号。变体号描述 {@code UUID} 的布局。 + *

+ * 变体号具有以下含意: + *

    + *
  • 0 为 NCS 向后兼容保留 + *
  • 2 IETF RFC 4122(Leach-Salz), 用于此类 + *
  • 6 保留,微软向后兼容 + *
  • 7 保留供以后定义使用 + *
+ * + * @return 此 {@code UUID} 相关联的变体号 + */ + public int variant() + { + // This field is composed of a varying number of bits. + // 0 - - Reserved for NCS backward compatibility + // 1 0 - The IETF aka Leach-Salz variant (used by this class) + // 1 1 0 Reserved, Microsoft backward compatibility + // 1 1 1 Reserved for future definition. + return (int) ((leastSigBits >>> (64 - (leastSigBits >>> 62))) & (leastSigBits >> 63)); + } + + /** + * 与此 UUID 相关联的时间戳值。 + * + *

+ * 60 位的时间戳值根据此 {@code UUID} 的 time_low、time_mid 和 time_hi 字段构造。
+ * 所得到的时间戳以 100 毫微秒为单位,从 UTC(通用协调时间) 1582 年 10 月 15 日零时开始。 + * + *

+ * 时间戳值仅在在基于时间的 UUID(其 version 类型为 1)中才有意义。
+ * 如果此 {@code UUID} 不是基于时间的 UUID,则此方法抛出 UnsupportedOperationException。 + * + * @throws UnsupportedOperationException 如果此 {@code UUID} 不是 version 为 1 的 UUID。 + */ + public long timestamp() throws UnsupportedOperationException + { + checkTimeBase(); + return (mostSigBits & 0x0FFFL) << 48 + | ((mostSigBits >> 16) & 0x0FFFFL) << 32 + | mostSigBits >>> 32; + } + + /** + * 与此 UUID 相关联的时钟序列值。 + * + *

+ * 14 位的时钟序列值根据此 UUID 的 clock_seq 字段构造。clock_seq 字段用于保证在基于时间的 UUID 中的时间唯一性。 + *

+ * {@code clockSequence} 值仅在基于时间的 UUID(其 version 类型为 1)中才有意义。 如果此 UUID 不是基于时间的 UUID,则此方法抛出 + * UnsupportedOperationException。 + * + * @return 此 {@code UUID} 的时钟序列 + * + * @throws UnsupportedOperationException 如果此 UUID 的 version 不为 1 + */ + public int clockSequence() throws UnsupportedOperationException + { + checkTimeBase(); + return (int) ((leastSigBits & 0x3FFF000000000000L) >>> 48); + } + + /** + * 与此 UUID 相关的节点值。 + * + *

+ * 48 位的节点值根据此 UUID 的 node 字段构造。此字段旨在用于保存机器的 IEEE 802 地址,该地址用于生成此 UUID 以保证空间唯一性。 + *

+ * 节点值仅在基于时间的 UUID(其 version 类型为 1)中才有意义。
+ * 如果此 UUID 不是基于时间的 UUID,则此方法抛出 UnsupportedOperationException。 + * + * @return 此 {@code UUID} 的节点值 + * + * @throws UnsupportedOperationException 如果此 UUID 的 version 不为 1 + */ + public long node() throws UnsupportedOperationException + { + checkTimeBase(); + return leastSigBits & 0x0000FFFFFFFFFFFFL; + } + + /** + * 返回此{@code UUID} 的字符串表现形式。 + * + *

+ * UUID 的字符串表示形式由此 BNF 描述: + * + *

+     * {@code
+     * UUID                   = ----
+     * time_low               = 4*
+     * time_mid               = 2*
+     * time_high_and_version  = 2*
+     * variant_and_sequence   = 2*
+     * node                   = 6*
+     * hexOctet               = 
+     * hexDigit               = [0-9a-fA-F]
+     * }
+     * 
+ * + * + * + * @return 此{@code UUID} 的字符串表现形式 + * @see #toString(boolean) + */ + @Override + public String toString() + { + return toString(false); + } + + /** + * 返回此{@code UUID} 的字符串表现形式。 + * + *

+ * UUID 的字符串表示形式由此 BNF 描述: + * + *

+     * {@code
+     * UUID                   = ----
+     * time_low               = 4*
+     * time_mid               = 2*
+     * time_high_and_version  = 2*
+     * variant_and_sequence   = 2*
+     * node                   = 6*
+     * hexOctet               = 
+     * hexDigit               = [0-9a-fA-F]
+     * }
+     * 
+ * + * + * + * @param isSimple 是否简单模式,简单模式为不带'-'的UUID字符串 + * @return 此{@code UUID} 的字符串表现形式 + */ + public String toString(boolean isSimple) + { + final StringBuilder builder = new StringBuilder(isSimple ? 32 : 36); + // time_low + builder.append(digits(mostSigBits >> 32, 8)); + if (!isSimple) + { + builder.append('-'); + } + // time_mid + builder.append(digits(mostSigBits >> 16, 4)); + if (!isSimple) + { + builder.append('-'); + } + // time_high_and_version + builder.append(digits(mostSigBits, 4)); + if (!isSimple) + { + builder.append('-'); + } + // variant_and_sequence + builder.append(digits(leastSigBits >> 48, 4)); + if (!isSimple) + { + builder.append('-'); + } + // node + builder.append(digits(leastSigBits, 12)); + + return builder.toString(); + } + + /** + * 返回此 UUID 的哈希码。 + * + * @return UUID 的哈希码值。 + */ + @Override + public int hashCode() + { + long hilo = mostSigBits ^ leastSigBits; + return ((int) (hilo >> 32)) ^ (int) hilo; + } + + /** + * 将此对象与指定对象比较。 + *

+ * 当且仅当参数不为 {@code null}、而是一个 UUID 对象、具有与此 UUID 相同的 varriant、包含相同的值(每一位均相同)时,结果才为 {@code true}。 + * + * @param obj 要与之比较的对象 + * + * @return 如果对象相同,则返回 {@code true};否则返回 {@code false} + */ + @Override + public boolean equals(Object obj) + { + if ((null == obj) || (obj.getClass() != UUID.class)) + { + return false; + } + UUID id = (UUID) obj; + return (mostSigBits == id.mostSigBits && leastSigBits == id.leastSigBits); + } + + // Comparison Operations + + /** + * 将此 UUID 与指定的 UUID 比较。 + * + *

+ * 如果两个 UUID 不同,且第一个 UUID 的最高有效字段大于第二个 UUID 的对应字段,则第一个 UUID 大于第二个 UUID。 + * + * @param val 与此 UUID 比较的 UUID + * + * @return 在此 UUID 小于、等于或大于 val 时,分别返回 -1、0 或 1。 + * + */ + @Override + public int compareTo(UUID val) + { + // The ordering is intentionally set up so that the UUIDs + // can simply be numerically compared as two numbers + return (this.mostSigBits < val.mostSigBits ? -1 : + (this.mostSigBits > val.mostSigBits ? 1 : + (Long.compare(this.leastSigBits, val.leastSigBits)))); + } + + // ------------------------------------------------------------------------------------------------------------------- + // Private method start + /** + * 返回指定数字对应的hex值 + * + * @param val 值 + * @param digits 位 + * @return 值 + */ + private static String digits(long val, int digits) + { + long hi = 1L << (digits * 4); + return Long.toHexString(hi | (val & (hi - 1))).substring(1); + } + + /** + * 检查是否为time-based版本UUID + */ + private void checkTimeBase() + { + if (version() != 1) + { + throw new UnsupportedOperationException("Not a time-based UUID"); + } + } + + /** + * 获取{@link SecureRandom},类提供加密的强随机数生成器 (RNG) + * + * @return {@link SecureRandom} + */ + public static SecureRandom getSecureRandom() + { + try + { + return SecureRandom.getInstance("SHA1PRNG"); + } + catch (NoSuchAlgorithmException e) + { + throw new UtilException(e); + } + } + + /** + * 获取随机数生成器对象
+ * ThreadLocalRandom是JDK 7之后提供并发产生随机数,能够解决多个线程发生的竞争争夺。 + * + * @return {@link ThreadLocalRandom} + */ + public static ThreadLocalRandom getRandom() + { + return ThreadLocalRandom.current(); + } +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/xss/Xss.java b/zzyl-common/src/main/java/com/zzyl/common/xss/Xss.java new file mode 100644 index 0000000..fd42811 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/xss/Xss.java @@ -0,0 +1,27 @@ +package com.zzyl.common.xss; + +import javax.validation.Constraint; +import javax.validation.Payload; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 自定义xss校验注解 + * + * @author ruoyi + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(value = { ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.PARAMETER }) +@Constraint(validatedBy = { XssValidator.class }) +public @interface Xss +{ + String message() + + default "不允许任何脚本运行"; + + Class[] groups() default {}; + + Class[] payload() default {}; +} diff --git a/zzyl-common/src/main/java/com/zzyl/common/xss/XssValidator.java b/zzyl-common/src/main/java/com/zzyl/common/xss/XssValidator.java new file mode 100644 index 0000000..fe4c295 --- /dev/null +++ b/zzyl-common/src/main/java/com/zzyl/common/xss/XssValidator.java @@ -0,0 +1,39 @@ +package com.zzyl.common.xss; + +import com.zzyl.common.utils.StringUtils; +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * 自定义xss校验注解实现 + * + * @author ruoyi + */ +public class XssValidator implements ConstraintValidator +{ + private static final String HTML_PATTERN = "<(\\S*?)[^>]*>.*?|<.*? />"; + + @Override + public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) + { + if (StringUtils.isBlank(value)) + { + return true; + } + return !containsHtml(value); + } + + public static boolean containsHtml(String value) + { + StringBuilder sHtml = new StringBuilder(); + Pattern pattern = Pattern.compile(HTML_PATTERN); + Matcher matcher = pattern.matcher(value); + while (matcher.find()) + { + sHtml.append(matcher.group()); + } + return pattern.matcher(sHtml).matches(); + } +} \ No newline at end of file diff --git a/zzyl-framework/pom.xml b/zzyl-framework/pom.xml new file mode 100644 index 0000000..5caa6cc --- /dev/null +++ b/zzyl-framework/pom.xml @@ -0,0 +1,75 @@ + + + + zzyl + com.zzyl + 3.8.8 + + 4.0.0 + + zzyl-framework + + + framework框架核心 + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-aop + + + + + com.alibaba + druid-spring-boot-starter + + + + + pro.fessional + kaptcha + + + servlet-api + javax.servlet + + + + + + + com.github.oshi + oshi-core + + + + + com.zzyl + zzyl-system + + + + com.huaweicloud.sdk + huaweicloud-sdk-core + 3.1.76 + + + com.huaweicloud.sdk + huaweicloud-sdk-iotda + 3.1.76 + + + + + \ No newline at end of file diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/aspectj/DataScopeAspect.java b/zzyl-framework/src/main/java/com/zzyl/framework/aspectj/DataScopeAspect.java new file mode 100644 index 0000000..b5cb9d2 --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/aspectj/DataScopeAspect.java @@ -0,0 +1,184 @@ +package com.zzyl.framework.aspectj; + +import java.util.ArrayList; +import java.util.List; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.springframework.stereotype.Component; +import com.zzyl.common.annotation.DataScope; +import com.zzyl.common.constant.UserConstants; +import com.zzyl.common.core.domain.BaseEntity; +import com.zzyl.common.core.domain.entity.SysRole; +import com.zzyl.common.core.domain.entity.SysUser; +import com.zzyl.common.core.domain.model.LoginUser; +import com.zzyl.common.core.text.Convert; +import com.zzyl.common.utils.SecurityUtils; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.framework.security.context.PermissionContextHolder; + +/** + * 数据过滤处理 + * + * @author ruoyi + */ +@Aspect +@Component +public class DataScopeAspect +{ + /** + * 全部数据权限 + */ + public static final String DATA_SCOPE_ALL = "1"; + + /** + * 自定数据权限 + */ + public static final String DATA_SCOPE_CUSTOM = "2"; + + /** + * 部门数据权限 + */ + public static final String DATA_SCOPE_DEPT = "3"; + + /** + * 部门及以下数据权限 + */ + public static final String DATA_SCOPE_DEPT_AND_CHILD = "4"; + + /** + * 仅本人数据权限 + */ + public static final String DATA_SCOPE_SELF = "5"; + + /** + * 数据权限过滤关键字 + */ + public static final String DATA_SCOPE = "dataScope"; + + @Before("@annotation(controllerDataScope)") + public void doBefore(JoinPoint point, DataScope controllerDataScope) throws Throwable + { + clearDataScope(point); + handleDataScope(point, controllerDataScope); + } + + protected void handleDataScope(final JoinPoint joinPoint, DataScope controllerDataScope) + { + // 获取当前的用户 + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (StringUtils.isNotNull(loginUser)) + { + SysUser currentUser = loginUser.getUser(); + // 如果是超级管理员,则不过滤数据 + if (StringUtils.isNotNull(currentUser) && !currentUser.isAdmin()) + { + String permission = StringUtils.defaultIfEmpty(controllerDataScope.permission(), PermissionContextHolder.getContext()); + dataScopeFilter(joinPoint, currentUser, controllerDataScope.deptAlias(), controllerDataScope.userAlias(), permission); + } + } + } + + /** + * 数据范围过滤 + * + * @param joinPoint 切点 + * @param user 用户 + * @param deptAlias 部门别名 + * @param userAlias 用户别名 + * @param permission 权限字符 + */ + public static void dataScopeFilter(JoinPoint joinPoint, SysUser user, String deptAlias, String userAlias, String permission) + { + StringBuilder sqlString = new StringBuilder(); + List conditions = new ArrayList(); + List scopeCustomIds = new ArrayList(); + user.getRoles().forEach(role -> { + if (DATA_SCOPE_CUSTOM.equals(role.getDataScope()) && StringUtils.equals(role.getStatus(), UserConstants.ROLE_NORMAL) && StringUtils.containsAny(role.getPermissions(), Convert.toStrArray(permission))) + { + scopeCustomIds.add(Convert.toStr(role.getRoleId())); + } + }); + + for (SysRole role : user.getRoles()) + { + String dataScope = role.getDataScope(); + if (conditions.contains(dataScope) || StringUtils.equals(role.getStatus(), UserConstants.ROLE_DISABLE)) + { + continue; + } + if (!StringUtils.containsAny(role.getPermissions(), Convert.toStrArray(permission))) + { + continue; + } + if (DATA_SCOPE_ALL.equals(dataScope)) + { + sqlString = new StringBuilder(); + conditions.add(dataScope); + break; + } + else if (DATA_SCOPE_CUSTOM.equals(dataScope)) + { + if (scopeCustomIds.size() > 1) + { + // 多个自定数据权限使用in查询,避免多次拼接。 + sqlString.append(StringUtils.format(" OR {}.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id in ({}) ) ", deptAlias, String.join(",", scopeCustomIds))); + } + else + { + sqlString.append(StringUtils.format(" OR {}.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id = {} ) ", deptAlias, role.getRoleId())); + } + } + else if (DATA_SCOPE_DEPT.equals(dataScope)) + { + sqlString.append(StringUtils.format(" OR {}.dept_id = {} ", deptAlias, user.getDeptId())); + } + else if (DATA_SCOPE_DEPT_AND_CHILD.equals(dataScope)) + { + sqlString.append(StringUtils.format(" OR {}.dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = {} or find_in_set( {} , ancestors ) )", deptAlias, user.getDeptId(), user.getDeptId())); + } + else if (DATA_SCOPE_SELF.equals(dataScope)) + { + if (StringUtils.isNotBlank(userAlias)) + { + sqlString.append(StringUtils.format(" OR {}.user_id = {} ", userAlias, user.getUserId())); + } + else + { + // 数据权限为仅本人且没有userAlias别名不查询任何数据 + sqlString.append(StringUtils.format(" OR {}.dept_id = 0 ", deptAlias)); + } + } + conditions.add(dataScope); + } + + // 角色都不包含传递过来的权限字符,这个时候sqlString也会为空,所以要限制一下,不查询任何数据 + if (StringUtils.isEmpty(conditions)) + { + sqlString.append(StringUtils.format(" OR {}.dept_id = 0 ", deptAlias)); + } + + if (StringUtils.isNotBlank(sqlString.toString())) + { + Object params = joinPoint.getArgs()[0]; + if (StringUtils.isNotNull(params) && params instanceof BaseEntity) + { + BaseEntity baseEntity = (BaseEntity) params; + baseEntity.getParams().put(DATA_SCOPE, " AND (" + sqlString.substring(4) + ")"); + } + } + } + + /** + * 拼接权限sql前先清空params.dataScope参数防止注入 + */ + private void clearDataScope(final JoinPoint joinPoint) + { + Object params = joinPoint.getArgs()[0]; + if (StringUtils.isNotNull(params) && params instanceof BaseEntity) + { + BaseEntity baseEntity = (BaseEntity) params; + baseEntity.getParams().put(DATA_SCOPE, ""); + } + } +} diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/aspectj/DataSourceAspect.java b/zzyl-framework/src/main/java/com/zzyl/framework/aspectj/DataSourceAspect.java new file mode 100644 index 0000000..a8f820c --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/aspectj/DataSourceAspect.java @@ -0,0 +1,72 @@ +package com.zzyl.framework.aspectj; + +import java.util.Objects; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; +import com.zzyl.common.annotation.DataSource; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.framework.datasource.DynamicDataSourceContextHolder; + +/** + * 多数据源处理 + * + * @author ruoyi + */ +@Aspect +@Order(1) +@Component +public class DataSourceAspect +{ + protected Logger logger = LoggerFactory.getLogger(getClass()); + + @Pointcut("@annotation(com.zzyl.common.annotation.DataSource)" + + "|| @within(com.zzyl.common.annotation.DataSource)") + public void dsPointCut() + { + + } + + @Around("dsPointCut()") + public Object around(ProceedingJoinPoint point) throws Throwable + { + DataSource dataSource = getDataSource(point); + + if (StringUtils.isNotNull(dataSource)) + { + DynamicDataSourceContextHolder.setDataSourceType(dataSource.value().name()); + } + + try + { + return point.proceed(); + } + finally + { + // 销毁数据源 在执行方法之后 + DynamicDataSourceContextHolder.clearDataSourceType(); + } + } + + /** + * 获取需要切换的数据源 + */ + public DataSource getDataSource(ProceedingJoinPoint point) + { + MethodSignature signature = (MethodSignature) point.getSignature(); + DataSource dataSource = AnnotationUtils.findAnnotation(signature.getMethod(), DataSource.class); + if (Objects.nonNull(dataSource)) + { + return dataSource; + } + + return AnnotationUtils.findAnnotation(signature.getDeclaringType(), DataSource.class); + } +} diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/aspectj/LogAspect.java b/zzyl-framework/src/main/java/com/zzyl/framework/aspectj/LogAspect.java new file mode 100644 index 0000000..564ae92 --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/aspectj/LogAspect.java @@ -0,0 +1,254 @@ +package com.zzyl.framework.aspectj; + +import java.util.Collection; +import java.util.Map; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.apache.commons.lang3.ArrayUtils; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.AfterReturning; +import org.aspectj.lang.annotation.AfterThrowing; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.NamedThreadLocal; +import org.springframework.stereotype.Component; +import org.springframework.validation.BindingResult; +import org.springframework.web.multipart.MultipartFile; +import com.alibaba.fastjson2.JSON; +import com.zzyl.common.annotation.Log; +import com.zzyl.common.core.domain.entity.SysUser; +import com.zzyl.common.core.domain.model.LoginUser; +import com.zzyl.common.enums.BusinessStatus; +import com.zzyl.common.enums.HttpMethod; +import com.zzyl.common.filter.PropertyPreExcludeFilter; +import com.zzyl.common.utils.SecurityUtils; +import com.zzyl.common.utils.ServletUtils; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.common.utils.ip.IpUtils; +import com.zzyl.framework.manager.AsyncManager; +import com.zzyl.framework.manager.factory.AsyncFactory; +import com.zzyl.system.domain.SysOperLog; + +/** + * 操作日志记录处理 + * + * @author ruoyi + */ +@Aspect +@Component +public class LogAspect +{ + private static final Logger log = LoggerFactory.getLogger(LogAspect.class); + + /** 排除敏感属性字段 */ + public static final String[] EXCLUDE_PROPERTIES = { "password", "oldPassword", "newPassword", "confirmPassword" }; + + /** 计算操作消耗时间 */ + private static final ThreadLocal TIME_THREADLOCAL = new NamedThreadLocal("Cost Time"); + + /** + * 处理请求前执行 + */ + @Before(value = "@annotation(controllerLog)") + public void boBefore(JoinPoint joinPoint, Log controllerLog) + { + TIME_THREADLOCAL.set(System.currentTimeMillis()); + } + + /** + * 处理完请求后执行 + * + * @param joinPoint 切点 + */ + @AfterReturning(pointcut = "@annotation(controllerLog)", returning = "jsonResult") + public void doAfterReturning(JoinPoint joinPoint, Log controllerLog, Object jsonResult) + { + handleLog(joinPoint, controllerLog, null, jsonResult); + } + + /** + * 拦截异常操作 + * + * @param joinPoint 切点 + * @param e 异常 + */ + @AfterThrowing(value = "@annotation(controllerLog)", throwing = "e") + public void doAfterThrowing(JoinPoint joinPoint, Log controllerLog, Exception e) + { + handleLog(joinPoint, controllerLog, e, null); + } + + protected void handleLog(final JoinPoint joinPoint, Log controllerLog, final Exception e, Object jsonResult) + { + try + { + // 获取当前的用户 + LoginUser loginUser = SecurityUtils.getLoginUser(); + + // *========数据库日志=========*// + SysOperLog operLog = new SysOperLog(); + operLog.setStatus(BusinessStatus.SUCCESS.ordinal()); + // 请求的地址 + String ip = IpUtils.getIpAddr(); + operLog.setOperIp(ip); + operLog.setOperUrl(StringUtils.substring(ServletUtils.getRequest().getRequestURI(), 0, 255)); + if (loginUser != null) + { + operLog.setOperName(loginUser.getUsername()); + SysUser currentUser = loginUser.getUser(); + if (StringUtils.isNotNull(currentUser) && StringUtils.isNotNull(currentUser.getDept())) + { + operLog.setDeptName(currentUser.getDept().getDeptName()); + } + } + + if (e != null) + { + operLog.setStatus(BusinessStatus.FAIL.ordinal()); + operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000)); + } + // 设置方法名称 + String className = joinPoint.getTarget().getClass().getName(); + String methodName = joinPoint.getSignature().getName(); + operLog.setMethod(className + "." + methodName + "()"); + // 设置请求方式 + operLog.setRequestMethod(ServletUtils.getRequest().getMethod()); + // 处理设置注解上的参数 + getControllerMethodDescription(joinPoint, controllerLog, operLog, jsonResult); + // 设置消耗时间 + operLog.setCostTime(System.currentTimeMillis() - TIME_THREADLOCAL.get()); + // 保存数据库 + AsyncManager.me().execute(AsyncFactory.recordOper(operLog)); + } + catch (Exception exp) + { + // 记录本地异常日志 + log.error("异常信息:{}", exp.getMessage()); + exp.printStackTrace(); + } + finally + { + TIME_THREADLOCAL.remove(); + } + } + + /** + * 获取注解中对方法的描述信息 用于Controller层注解 + * + * @param log 日志 + * @param operLog 操作日志 + * @throws Exception + */ + public void getControllerMethodDescription(JoinPoint joinPoint, Log log, SysOperLog operLog, Object jsonResult) throws Exception + { + // 设置action动作 + operLog.setBusinessType(log.businessType().ordinal()); + // 设置标题 + operLog.setTitle(log.title()); + // 设置操作人类别 + operLog.setOperatorType(log.operatorType().ordinal()); + // 是否需要保存request,参数和值 + if (log.isSaveRequestData()) + { + // 获取参数的信息,传入到数据库中。 + setRequestValue(joinPoint, operLog, log.excludeParamNames()); + } + // 是否需要保存response,参数和值 + if (log.isSaveResponseData() && StringUtils.isNotNull(jsonResult)) + { + operLog.setJsonResult(StringUtils.substring(JSON.toJSONString(jsonResult), 0, 2000)); + } + } + + /** + * 获取请求的参数,放到log中 + * + * @param operLog 操作日志 + * @throws Exception 异常 + */ + private void setRequestValue(JoinPoint joinPoint, SysOperLog operLog, String[] excludeParamNames) throws Exception + { + Map paramsMap = ServletUtils.getParamMap(ServletUtils.getRequest()); + String requestMethod = operLog.getRequestMethod(); + if (StringUtils.isEmpty(paramsMap) && StringUtils.equalsAny(requestMethod, HttpMethod.PUT.name(), HttpMethod.POST.name(), HttpMethod.DELETE.name())) + { + String params = argsArrayToString(joinPoint.getArgs(), excludeParamNames); + operLog.setOperParam(StringUtils.substring(params, 0, 2000)); + } + else + { + operLog.setOperParam(StringUtils.substring(JSON.toJSONString(paramsMap, excludePropertyPreFilter(excludeParamNames)), 0, 2000)); + } + } + + /** + * 参数拼装 + */ + private String argsArrayToString(Object[] paramsArray, String[] excludeParamNames) + { + String params = ""; + if (paramsArray != null && paramsArray.length > 0) + { + for (Object o : paramsArray) + { + if (StringUtils.isNotNull(o) && !isFilterObject(o)) + { + try + { + String jsonObj = JSON.toJSONString(o, excludePropertyPreFilter(excludeParamNames)); + params += jsonObj.toString() + " "; + } + catch (Exception e) + { + } + } + } + } + return params.trim(); + } + + /** + * 忽略敏感属性 + */ + public PropertyPreExcludeFilter excludePropertyPreFilter(String[] excludeParamNames) + { + return new PropertyPreExcludeFilter().addExcludes(ArrayUtils.addAll(EXCLUDE_PROPERTIES, excludeParamNames)); + } + + /** + * 判断是否需要过滤的对象。 + * + * @param o 对象信息。 + * @return 如果是需要过滤的对象,则返回true;否则返回false。 + */ + @SuppressWarnings("rawtypes") + public boolean isFilterObject(final Object o) + { + Class clazz = o.getClass(); + if (clazz.isArray()) + { + return clazz.getComponentType().isAssignableFrom(MultipartFile.class); + } + else if (Collection.class.isAssignableFrom(clazz)) + { + Collection collection = (Collection) o; + for (Object value : collection) + { + return value instanceof MultipartFile; + } + } + else if (Map.class.isAssignableFrom(clazz)) + { + Map map = (Map) o; + for (Object value : map.entrySet()) + { + Map.Entry entry = (Map.Entry) value; + return entry.getValue() instanceof MultipartFile; + } + } + return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse + || o instanceof BindingResult; + } +} diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/aspectj/RateLimiterAspect.java b/zzyl-framework/src/main/java/com/zzyl/framework/aspectj/RateLimiterAspect.java new file mode 100644 index 0000000..fdc7aed --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/aspectj/RateLimiterAspect.java @@ -0,0 +1,89 @@ +package com.zzyl.framework.aspectj; + +import java.lang.reflect.Method; +import java.util.Collections; +import java.util.List; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.reflect.MethodSignature; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.script.RedisScript; +import org.springframework.stereotype.Component; +import com.zzyl.common.annotation.RateLimiter; +import com.zzyl.common.enums.LimitType; +import com.zzyl.common.exception.ServiceException; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.common.utils.ip.IpUtils; + +/** + * 限流处理 + * + * @author ruoyi + */ +@Aspect +@Component +public class RateLimiterAspect +{ + private static final Logger log = LoggerFactory.getLogger(RateLimiterAspect.class); + + private RedisTemplate redisTemplate; + + private RedisScript limitScript; + + @Autowired + public void setRedisTemplate1(RedisTemplate redisTemplate) + { + this.redisTemplate = redisTemplate; + } + + @Autowired + public void setLimitScript(RedisScript limitScript) + { + this.limitScript = limitScript; + } + + @Before("@annotation(rateLimiter)") + public void doBefore(JoinPoint point, RateLimiter rateLimiter) throws Throwable + { + int time = rateLimiter.time(); + int count = rateLimiter.count(); + + String combineKey = getCombineKey(rateLimiter, point); + List keys = Collections.singletonList(combineKey); + try + { + Long number = redisTemplate.execute(limitScript, keys, count, time); + if (StringUtils.isNull(number) || number.intValue() > count) + { + throw new ServiceException("访问过于频繁,请稍候再试"); + } + log.info("限制请求'{}',当前请求'{}',缓存key'{}'", count, number.intValue(), combineKey); + } + catch (ServiceException e) + { + throw e; + } + catch (Exception e) + { + throw new RuntimeException("服务器限流异常,请稍候再试"); + } + } + + public String getCombineKey(RateLimiter rateLimiter, JoinPoint point) + { + StringBuffer stringBuffer = new StringBuffer(rateLimiter.key()); + if (rateLimiter.limitType() == LimitType.IP) + { + stringBuffer.append(IpUtils.getIpAddr()).append("-"); + } + MethodSignature signature = (MethodSignature) point.getSignature(); + Method method = signature.getMethod(); + Class targetClass = method.getDeclaringClass(); + stringBuffer.append(targetClass.getName()).append("-").append(method.getName()); + return stringBuffer.toString(); + } +} diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/config/ApplicationConfig.java b/zzyl-framework/src/main/java/com/zzyl/framework/config/ApplicationConfig.java new file mode 100644 index 0000000..8300400 --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/config/ApplicationConfig.java @@ -0,0 +1,30 @@ +package com.zzyl.framework.config; + +import java.util.TimeZone; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.EnableAspectJAutoProxy; + +/** + * 程序注解配置 + * + * @author ruoyi + */ +@Configuration +// 表示通过aop框架暴露该代理对象,AopContext能够访问 +@EnableAspectJAutoProxy(exposeProxy = true) +// 指定要扫描的Mapper类的包的路径 +@MapperScan("com.zzyl.**.mapper") +public class ApplicationConfig +{ + /** + * 时区配置 + */ + @Bean + public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization() + { + return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder.timeZone(TimeZone.getDefault()); + } +} diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/config/CaptchaConfig.java b/zzyl-framework/src/main/java/com/zzyl/framework/config/CaptchaConfig.java new file mode 100644 index 0000000..d1da767 --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/config/CaptchaConfig.java @@ -0,0 +1,83 @@ +package com.zzyl.framework.config; + +import java.util.Properties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import com.google.code.kaptcha.impl.DefaultKaptcha; +import com.google.code.kaptcha.util.Config; +import static com.google.code.kaptcha.Constants.*; + +/** + * 验证码配置 + * + * @author ruoyi + */ +@Configuration +public class CaptchaConfig +{ + @Bean(name = "captchaProducer") + public DefaultKaptcha getKaptchaBean() + { + DefaultKaptcha defaultKaptcha = new DefaultKaptcha(); + Properties properties = new Properties(); + // 是否有边框 默认为true 我们可以自己设置yes,no + properties.setProperty(KAPTCHA_BORDER, "yes"); + // 验证码文本字符颜色 默认为Color.BLACK + properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "black"); + // 验证码图片宽度 默认为200 + properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160"); + // 验证码图片高度 默认为50 + properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60"); + // 验证码文本字符大小 默认为40 + properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "38"); + // KAPTCHA_SESSION_KEY + properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCode"); + // 验证码文本字符长度 默认为5 + properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "4"); + // 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize) + properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier"); + // 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy + properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy"); + Config config = new Config(properties); + defaultKaptcha.setConfig(config); + return defaultKaptcha; + } + + @Bean(name = "captchaProducerMath") + public DefaultKaptcha getKaptchaBeanMath() + { + DefaultKaptcha defaultKaptcha = new DefaultKaptcha(); + Properties properties = new Properties(); + // 是否有边框 默认为true 我们可以自己设置yes,no + properties.setProperty(KAPTCHA_BORDER, "yes"); + // 边框颜色 默认为Color.BLACK + properties.setProperty(KAPTCHA_BORDER_COLOR, "105,179,90"); + // 验证码文本字符颜色 默认为Color.BLACK + properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "blue"); + // 验证码图片宽度 默认为200 + properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160"); + // 验证码图片高度 默认为50 + properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60"); + // 验证码文本字符大小 默认为40 + properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "35"); + // KAPTCHA_SESSION_KEY + properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCodeMath"); + // 验证码文本生成器 + properties.setProperty(KAPTCHA_TEXTPRODUCER_IMPL, "com.zzyl.framework.config.KaptchaTextCreator"); + // 验证码文本字符间距 默认为2 + properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_SPACE, "3"); + // 验证码文本字符长度 默认为5 + properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "6"); + // 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize) + properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier"); + // 验证码噪点颜色 默认为Color.BLACK + properties.setProperty(KAPTCHA_NOISE_COLOR, "white"); + // 干扰实现类 + properties.setProperty(KAPTCHA_NOISE_IMPL, "com.google.code.kaptcha.impl.NoNoise"); + // 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy + properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy"); + Config config = new Config(properties); + defaultKaptcha.setConfig(config); + return defaultKaptcha; + } +} diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/config/DruidConfig.java b/zzyl-framework/src/main/java/com/zzyl/framework/config/DruidConfig.java new file mode 100644 index 0000000..0a0c902 --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/config/DruidConfig.java @@ -0,0 +1,126 @@ +package com.zzyl.framework.config; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.sql.DataSource; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import com.alibaba.druid.pool.DruidDataSource; +import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder; +import com.alibaba.druid.spring.boot.autoconfigure.properties.DruidStatProperties; +import com.alibaba.druid.util.Utils; +import com.zzyl.common.enums.DataSourceType; +import com.zzyl.common.utils.spring.SpringUtils; +import com.zzyl.framework.config.properties.DruidProperties; +import com.zzyl.framework.datasource.DynamicDataSource; + +/** + * druid 配置多数据源 + * + * @author ruoyi + */ +@Configuration +public class DruidConfig +{ + @Bean + @ConfigurationProperties("spring.datasource.druid.master") + public DataSource masterDataSource(DruidProperties druidProperties) + { + DruidDataSource dataSource = DruidDataSourceBuilder.create().build(); + return druidProperties.dataSource(dataSource); + } + + @Bean + @ConfigurationProperties("spring.datasource.druid.slave") + @ConditionalOnProperty(prefix = "spring.datasource.druid.slave", name = "enabled", havingValue = "true") + public DataSource slaveDataSource(DruidProperties druidProperties) + { + DruidDataSource dataSource = DruidDataSourceBuilder.create().build(); + return druidProperties.dataSource(dataSource); + } + + @Bean(name = "dynamicDataSource") + @Primary + public DynamicDataSource dataSource(DataSource masterDataSource) + { + Map targetDataSources = new HashMap<>(); + targetDataSources.put(DataSourceType.MASTER.name(), masterDataSource); + setDataSource(targetDataSources, DataSourceType.SLAVE.name(), "slaveDataSource"); + return new DynamicDataSource(masterDataSource, targetDataSources); + } + + /** + * 设置数据源 + * + * @param targetDataSources 备选数据源集合 + * @param sourceName 数据源名称 + * @param beanName bean名称 + */ + public void setDataSource(Map targetDataSources, String sourceName, String beanName) + { + try + { + DataSource dataSource = SpringUtils.getBean(beanName); + targetDataSources.put(sourceName, dataSource); + } + catch (Exception e) + { + } + } + + /** + * 去除监控页面底部的广告 + */ + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Bean + @ConditionalOnProperty(name = "spring.datasource.druid.statViewServlet.enabled", havingValue = "true") + public FilterRegistrationBean removeDruidFilterRegistrationBean(DruidStatProperties properties) + { + // 获取web监控页面的参数 + DruidStatProperties.StatViewServlet config = properties.getStatViewServlet(); + // 提取common.js的配置路径 + String pattern = config.getUrlPattern() != null ? config.getUrlPattern() : "/druid/*"; + String commonJsPattern = pattern.replaceAll("\\*", "js/common.js"); + final String filePath = "support/http/resources/js/common.js"; + // 创建filter进行过滤 + Filter filter = new Filter() + { + @Override + public void init(javax.servlet.FilterConfig filterConfig) throws ServletException + { + } + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException + { + chain.doFilter(request, response); + // 重置缓冲区,响应头不会被重置 + response.resetBuffer(); + // 获取common.js + String text = Utils.readFromResource(filePath); + // 正则替换banner, 除去底部的广告信息 + text = text.replaceAll("
", ""); + text = text.replaceAll("powered.*?shrek.wang", ""); + response.getWriter().write(text); + } + @Override + public void destroy() + { + } + }; + FilterRegistrationBean registrationBean = new FilterRegistrationBean(); + registrationBean.setFilter(filter); + registrationBean.addUrlPatterns(commonJsPattern); + return registrationBean; + } +} diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/config/FastJson2JsonRedisSerializer.java b/zzyl-framework/src/main/java/com/zzyl/framework/config/FastJson2JsonRedisSerializer.java new file mode 100644 index 0000000..ce2f5a6 --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/config/FastJson2JsonRedisSerializer.java @@ -0,0 +1,52 @@ +package com.zzyl.framework.config; + +import java.nio.charset.Charset; +import org.springframework.data.redis.serializer.RedisSerializer; +import org.springframework.data.redis.serializer.SerializationException; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONReader; +import com.alibaba.fastjson2.JSONWriter; +import com.alibaba.fastjson2.filter.Filter; +import com.zzyl.common.constant.Constants; + +/** + * Redis使用FastJson序列化 + * + * @author ruoyi + */ +public class FastJson2JsonRedisSerializer implements RedisSerializer +{ + public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); + + static final Filter AUTO_TYPE_FILTER = JSONReader.autoTypeFilter(Constants.JSON_WHITELIST_STR); + + private Class clazz; + + public FastJson2JsonRedisSerializer(Class clazz) + { + super(); + this.clazz = clazz; + } + + @Override + public byte[] serialize(T t) throws SerializationException + { + if (t == null) + { + return new byte[0]; + } + return JSON.toJSONString(t, JSONWriter.Feature.WriteClassName).getBytes(DEFAULT_CHARSET); + } + + @Override + public T deserialize(byte[] bytes) throws SerializationException + { + if (bytes == null || bytes.length <= 0) + { + return null; + } + String str = new String(bytes, DEFAULT_CHARSET); + + return JSON.parseObject(str, clazz, AUTO_TYPE_FILTER); + } +} diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/config/FilterConfig.java b/zzyl-framework/src/main/java/com/zzyl/framework/config/FilterConfig.java new file mode 100644 index 0000000..4455748 --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/config/FilterConfig.java @@ -0,0 +1,58 @@ +package com.zzyl.framework.config; + +import java.util.HashMap; +import java.util.Map; +import javax.servlet.DispatcherType; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import com.zzyl.common.filter.RepeatableFilter; +import com.zzyl.common.filter.XssFilter; +import com.zzyl.common.utils.StringUtils; + +/** + * Filter配置 + * + * @author ruoyi + */ +@Configuration +public class FilterConfig +{ + @Value("${xss.excludes}") + private String excludes; + + @Value("${xss.urlPatterns}") + private String urlPatterns; + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Bean + @ConditionalOnProperty(value = "xss.enabled", havingValue = "true") + public FilterRegistrationBean xssFilterRegistration() + { + FilterRegistrationBean registration = new FilterRegistrationBean(); + registration.setDispatcherTypes(DispatcherType.REQUEST); + registration.setFilter(new XssFilter()); + registration.addUrlPatterns(StringUtils.split(urlPatterns, ",")); + registration.setName("xssFilter"); + registration.setOrder(FilterRegistrationBean.HIGHEST_PRECEDENCE); + Map initParameters = new HashMap(); + initParameters.put("excludes", excludes); + registration.setInitParameters(initParameters); + return registration; + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Bean + public FilterRegistrationBean someFilterRegistration() + { + FilterRegistrationBean registration = new FilterRegistrationBean(); + registration.setFilter(new RepeatableFilter()); + registration.addUrlPatterns("/*"); + registration.setName("repeatableFilter"); + registration.setOrder(FilterRegistrationBean.LOWEST_PRECEDENCE); + return registration; + } + +} diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/config/I18nConfig.java b/zzyl-framework/src/main/java/com/zzyl/framework/config/I18nConfig.java new file mode 100644 index 0000000..b686a2d --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/config/I18nConfig.java @@ -0,0 +1,43 @@ +package com.zzyl.framework.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.LocaleResolver; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import org.springframework.web.servlet.i18n.LocaleChangeInterceptor; +import org.springframework.web.servlet.i18n.SessionLocaleResolver; +import com.zzyl.common.constant.Constants; + +/** + * 资源文件配置加载 + * + * @author ruoyi + */ +@Configuration +public class I18nConfig implements WebMvcConfigurer +{ + @Bean + public LocaleResolver localeResolver() + { + SessionLocaleResolver slr = new SessionLocaleResolver(); + // 默认语言 + slr.setDefaultLocale(Constants.DEFAULT_LOCALE); + return slr; + } + + @Bean + public LocaleChangeInterceptor localeChangeInterceptor() + { + LocaleChangeInterceptor lci = new LocaleChangeInterceptor(); + // 参数名 + lci.setParamName("lang"); + return lci; + } + + @Override + public void addInterceptors(InterceptorRegistry registry) + { + registry.addInterceptor(localeChangeInterceptor()); + } +} diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/config/IotClientConfig.java b/zzyl-framework/src/main/java/com/zzyl/framework/config/IotClientConfig.java new file mode 100644 index 0000000..0426b49 --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/config/IotClientConfig.java @@ -0,0 +1,41 @@ +package com.zzyl.framework.config; + +import com.huaweicloud.sdk.core.auth.BasicCredentials; +import com.huaweicloud.sdk.core.auth.ICredential; +import com.huaweicloud.sdk.core.region.Region; +import com.huaweicloud.sdk.iotda.v5.IoTDAClient; +import com.zzyl.framework.config.properties.HuaWeiIotConfigProperties; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * TODO + * + * @author Zhy + * @version 1.0 + * @date 2025-03-05 19:03 + */ +@Configuration +public class IotClientConfig { + + @Autowired + private HuaWeiIotConfigProperties huaWeiIotConfigProperties; + + @Bean + public IoTDAClient huaWeiIotInstance() { + ICredential auth = new BasicCredentials().withAk(huaWeiIotConfigProperties.getAk()) + .withSk(huaWeiIotConfigProperties.getSk()) + // 标准版/企业版需要使用衍生算法,基础版请删除配置"withDerivedPredicate" + .withDerivedPredicate(BasicCredentials.DEFAULT_DERIVED_PREDICATE) + .withProjectId(huaWeiIotConfigProperties.getProjectId()); + + return IoTDAClient.newBuilder().withCredential(auth) + // 标准版/企业版:需自行创建Region对象,基础版:请使用IoTDARegion的region对象,如"withRegion(IoTDARegion.CN_NORTH_4)" + .withRegion(new Region(huaWeiIotConfigProperties.getRegionId(), huaWeiIotConfigProperties.getEndpoint())) + // .withRegion(IoTDARegion.CN_NORTH_4) + .build(); + } + +} diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/config/KaptchaTextCreator.java b/zzyl-framework/src/main/java/com/zzyl/framework/config/KaptchaTextCreator.java new file mode 100644 index 0000000..c6ad9ab --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/config/KaptchaTextCreator.java @@ -0,0 +1,68 @@ +package com.zzyl.framework.config; + +import java.util.Random; +import com.google.code.kaptcha.text.impl.DefaultTextCreator; + +/** + * 验证码文本生成器 + * + * @author ruoyi + */ +public class KaptchaTextCreator extends DefaultTextCreator +{ + private static final String[] CNUMBERS = "0,1,2,3,4,5,6,7,8,9,10".split(","); + + @Override + public String getText() + { + Integer result = 0; + Random random = new Random(); + int x = random.nextInt(10); + int y = random.nextInt(10); + StringBuilder suChinese = new StringBuilder(); + int randomoperands = random.nextInt(3); + if (randomoperands == 0) + { + result = x * y; + suChinese.append(CNUMBERS[x]); + suChinese.append("*"); + suChinese.append(CNUMBERS[y]); + } + else if (randomoperands == 1) + { + if ((x != 0) && y % x == 0) + { + result = y / x; + suChinese.append(CNUMBERS[y]); + suChinese.append("/"); + suChinese.append(CNUMBERS[x]); + } + else + { + result = x + y; + suChinese.append(CNUMBERS[x]); + suChinese.append("+"); + suChinese.append(CNUMBERS[y]); + } + } + else + { + if (x >= y) + { + result = x - y; + suChinese.append(CNUMBERS[x]); + suChinese.append("-"); + suChinese.append(CNUMBERS[y]); + } + else + { + result = y - x; + suChinese.append(CNUMBERS[y]); + suChinese.append("-"); + suChinese.append(CNUMBERS[x]); + } + } + suChinese.append("=?@" + result); + return suChinese.toString(); + } +} \ No newline at end of file diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/config/MyBatisConfig.java b/zzyl-framework/src/main/java/com/zzyl/framework/config/MyBatisConfig.java new file mode 100644 index 0000000..a66bde4 --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/config/MyBatisConfig.java @@ -0,0 +1,132 @@ +//package com.zzyl.framework.config; +// +//import java.io.IOException; +//import java.util.ArrayList; +//import java.util.Arrays; +//import java.util.HashSet; +//import java.util.List; +//import javax.sql.DataSource; +//import org.apache.ibatis.io.VFS; +//import org.apache.ibatis.session.SqlSessionFactory; +//import org.mybatis.spring.SqlSessionFactoryBean; +//import org.mybatis.spring.boot.autoconfigure.SpringBootVFS; +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.context.annotation.Bean; +//import org.springframework.context.annotation.Configuration; +//import org.springframework.core.env.Environment; +//import org.springframework.core.io.DefaultResourceLoader; +//import org.springframework.core.io.Resource; +//import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +//import org.springframework.core.io.support.ResourcePatternResolver; +//import org.springframework.core.type.classreading.CachingMetadataReaderFactory; +//import org.springframework.core.type.classreading.MetadataReader; +//import org.springframework.core.type.classreading.MetadataReaderFactory; +//import org.springframework.util.ClassUtils; +//import com.zzyl.common.utils.StringUtils; +// +///** +// * Mybatis支持*匹配扫描包 +// * +// * @author ruoyi +// */ +//@Configuration +//public class MyBatisConfig +//{ +// @Autowired +// private Environment env; +// +// static final String DEFAULT_RESOURCE_PATTERN = "**/*.class"; +// +// public static String setTypeAliasesPackage(String typeAliasesPackage) +// { +// ResourcePatternResolver resolver = (ResourcePatternResolver) new PathMatchingResourcePatternResolver(); +// MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resolver); +// List allResult = new ArrayList(); +// try +// { +// for (String aliasesPackage : typeAliasesPackage.split(",")) +// { +// List result = new ArrayList(); +// aliasesPackage = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +// + ClassUtils.convertClassNameToResourcePath(aliasesPackage.trim()) + "/" + DEFAULT_RESOURCE_PATTERN; +// Resource[] resources = resolver.getResources(aliasesPackage); +// if (resources != null && resources.length > 0) +// { +// MetadataReader metadataReader = null; +// for (Resource resource : resources) +// { +// if (resource.isReadable()) +// { +// metadataReader = metadataReaderFactory.getMetadataReader(resource); +// try +// { +// result.add(Class.forName(metadataReader.getClassMetadata().getClassName()).getPackage().getName()); +// } +// catch (ClassNotFoundException e) +// { +// e.printStackTrace(); +// } +// } +// } +// } +// if (result.size() > 0) +// { +// HashSet hashResult = new HashSet(result); +// allResult.addAll(hashResult); +// } +// } +// if (allResult.size() > 0) +// { +// typeAliasesPackage = String.join(",", (String[]) allResult.toArray(new String[0])); +// } +// else +// { +// throw new RuntimeException("mybatis typeAliasesPackage 路径扫描错误,参数typeAliasesPackage:" + typeAliasesPackage + "未找到任何包"); +// } +// } +// catch (IOException e) +// { +// e.printStackTrace(); +// } +// return typeAliasesPackage; +// } +// +// public Resource[] resolveMapperLocations(String[] mapperLocations) +// { +// ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver(); +// List resources = new ArrayList(); +// if (mapperLocations != null) +// { +// for (String mapperLocation : mapperLocations) +// { +// try +// { +// Resource[] mappers = resourceResolver.getResources(mapperLocation); +// resources.addAll(Arrays.asList(mappers)); +// } +// catch (IOException e) +// { +// // ignore +// } +// } +// } +// return resources.toArray(new Resource[resources.size()]); +// } +// +// @Bean +// public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception +// { +// String typeAliasesPackage = env.getProperty("mybatis.typeAliasesPackage"); +// String mapperLocations = env.getProperty("mybatis.mapperLocations"); +// String configLocation = env.getProperty("mybatis.configLocation"); +// typeAliasesPackage = setTypeAliasesPackage(typeAliasesPackage); +// VFS.addImplClass(SpringBootVFS.class); +// +// final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); +// sessionFactory.setDataSource(dataSource); +// sessionFactory.setTypeAliasesPackage(typeAliasesPackage); +// sessionFactory.setMapperLocations(resolveMapperLocations(StringUtils.split(mapperLocations, ","))); +// sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(configLocation)); +// return sessionFactory.getObject(); +// } +//} \ No newline at end of file diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/config/MybatisPlusConfig.java b/zzyl-framework/src/main/java/com/zzyl/framework/config/MybatisPlusConfig.java new file mode 100644 index 0000000..b518f2a --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/config/MybatisPlusConfig.java @@ -0,0 +1,59 @@ +package com.zzyl.framework.config; + +import com.baomidou.mybatisplus.annotation.DbType; +import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; +import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor; +import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor; +import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +/** + * Mybatis Plus 配置 + * + * @author ruoyi + */ +@EnableTransactionManagement(proxyTargetClass = true) +@Configuration +public class MybatisPlusConfig { + + @Bean + public MybatisPlusInterceptor mybatisPlusInterceptor() { + MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); + // 分页插件 + interceptor.addInnerInterceptor(paginationInnerInterceptor()); + // 乐观锁插件 + interceptor.addInnerInterceptor(optimisticLockerInnerInterceptor()); + // 阻断插件 + interceptor.addInnerInterceptor(blockAttackInnerInterceptor()); + return interceptor; + } + + /** + * 分页插件,自动识别数据库类型 https://baomidou.com/guide/interceptor-pagination.html + */ + public PaginationInnerInterceptor paginationInnerInterceptor() { + PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(); + // 设置数据库类型为mysql + paginationInnerInterceptor.setDbType(DbType.MYSQL); + // 设置最大单页限制数量,默认 500 条,-1 不受限制 + paginationInnerInterceptor.setMaxLimit(-1L); + return paginationInnerInterceptor; + } + + /** + * 乐观锁插件 https://baomidou.com/guide/interceptor-optimistic-locker.html + */ + public OptimisticLockerInnerInterceptor optimisticLockerInnerInterceptor() { + return new OptimisticLockerInnerInterceptor(); + } + + /** + * 如果是对全表的删除或更新操作,就会终止该操作 https://baomidou.com/guide/interceptor-block-attack.html + */ + public BlockAttackInnerInterceptor blockAttackInnerInterceptor() { + return new BlockAttackInnerInterceptor(); + } + +} \ No newline at end of file diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/config/RedisConfig.java b/zzyl-framework/src/main/java/com/zzyl/framework/config/RedisConfig.java new file mode 100644 index 0000000..cc3adeb --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/config/RedisConfig.java @@ -0,0 +1,69 @@ +package com.zzyl.framework.config; + +import org.springframework.cache.annotation.CachingConfigurerSupport; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.script.DefaultRedisScript; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +/** + * redis配置 + * + * @author ruoyi + */ +@Configuration +@EnableCaching +public class RedisConfig extends CachingConfigurerSupport +{ + @Bean + @SuppressWarnings(value = { "unchecked", "rawtypes" }) + public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) + { + RedisTemplate template = new RedisTemplate<>(); + template.setConnectionFactory(connectionFactory); + + FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class); + + // 使用StringRedisSerializer来序列化和反序列化redis的key值 + template.setKeySerializer(new StringRedisSerializer()); + template.setValueSerializer(serializer); + + // Hash的key也采用StringRedisSerializer的序列化方式 + template.setHashKeySerializer(new StringRedisSerializer()); + template.setHashValueSerializer(serializer); + + template.afterPropertiesSet(); + return template; + } + + @Bean + public DefaultRedisScript limitScript() + { + DefaultRedisScript redisScript = new DefaultRedisScript<>(); + redisScript.setScriptText(limitScriptText()); + redisScript.setResultType(Long.class); + return redisScript; + } + + /** + * 限流脚本 + */ + private String limitScriptText() + { + return "local key = KEYS[1]\n" + + "local count = tonumber(ARGV[1])\n" + + "local time = tonumber(ARGV[2])\n" + + "local current = redis.call('get', key);\n" + + "if current and tonumber(current) > count then\n" + + " return tonumber(current);\n" + + "end\n" + + "current = redis.call('incr', key)\n" + + "if tonumber(current) == 1 then\n" + + " redis.call('expire', key, time)\n" + + "end\n" + + "return tonumber(current);"; + } +} diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/config/ResourcesConfig.java b/zzyl-framework/src/main/java/com/zzyl/framework/config/ResourcesConfig.java new file mode 100644 index 0000000..0ee41f1 --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/config/ResourcesConfig.java @@ -0,0 +1,83 @@ +package com.zzyl.framework.config; + +import java.util.concurrent.TimeUnit; + +import com.zzyl.framework.interceptor.MemberInterceptor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.CacheControl; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; +import org.springframework.web.filter.CorsFilter; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import com.zzyl.common.config.RuoYiConfig; +import com.zzyl.common.constant.Constants; +import com.zzyl.framework.interceptor.RepeatSubmitInterceptor; + +/** + * 通用配置 + * + * @author ruoyi + */ +@Configuration +public class ResourcesConfig implements WebMvcConfigurer +{ + @Autowired + private RepeatSubmitInterceptor repeatSubmitInterceptor; + @Autowired + private MemberInterceptor memberInterceptor; + + private static final String[] EXCLUDE_PATH_PATTERNS = new String[] { + "/member/user/login", + "/member/roomTypes" + }; + + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) + { + /** 本地文件上传路径 */ + registry.addResourceHandler(Constants.RESOURCE_PREFIX + "/**") + .addResourceLocations("file:" + RuoYiConfig.getProfile() + "/"); + + /** swagger配置 */ + registry.addResourceHandler("/swagger-ui/**") + .addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/") + .setCacheControl(CacheControl.maxAge(5, TimeUnit.HOURS).cachePublic()); + } + + /** + * 自定义拦截规则 + */ + @Override + public void addInterceptors(InterceptorRegistry registry) + { + registry.addInterceptor(repeatSubmitInterceptor).addPathPatterns("/**"); + registry.addInterceptor(memberInterceptor).excludePathPatterns(EXCLUDE_PATH_PATTERNS).addPathPatterns("/member/**"); + } + + /** + * 跨域配置 + */ + @Bean + public CorsFilter corsFilter() + { + CorsConfiguration config = new CorsConfiguration(); + config.setAllowCredentials(true); + // 设置访问源地址 + config.addAllowedOriginPattern("*"); + // 设置访问源请求头 + config.addAllowedHeader("*"); + // 设置访问源请求方法 + config.addAllowedMethod("*"); + // 有效期 1800秒 + config.setMaxAge(1800L); + // 添加映射路径,拦截一切请求 + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + source.registerCorsConfiguration("/**", config); + // 返回新的CorsFilter + return new CorsFilter(source); + } +} \ No newline at end of file diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/config/SecurityConfig.java b/zzyl-framework/src/main/java/com/zzyl/framework/config/SecurityConfig.java new file mode 100644 index 0000000..9bdea83 --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/config/SecurityConfig.java @@ -0,0 +1,139 @@ +package com.zzyl.framework.config; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpMethod; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.ProviderManager; +import org.springframework.security.authentication.dao.DaoAuthenticationProvider; +import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.security.web.authentication.logout.LogoutFilter; +import org.springframework.web.filter.CorsFilter; +import com.zzyl.framework.config.properties.PermitAllUrlProperties; +import com.zzyl.framework.security.filter.JwtAuthenticationTokenFilter; +import com.zzyl.framework.security.handle.AuthenticationEntryPointImpl; +import com.zzyl.framework.security.handle.LogoutSuccessHandlerImpl; + +/** + * spring security配置 + * + * @author ruoyi + */ +@EnableMethodSecurity(prePostEnabled = true, securedEnabled = true) +@Configuration +public class SecurityConfig +{ + /** + * 自定义用户认证逻辑 + */ + @Autowired + private UserDetailsService userDetailsService; + + /** + * 认证失败处理类 + */ + @Autowired + private AuthenticationEntryPointImpl unauthorizedHandler; + + /** + * 退出处理类 + */ + @Autowired + private LogoutSuccessHandlerImpl logoutSuccessHandler; + + /** + * token认证过滤器 + */ + @Autowired + private JwtAuthenticationTokenFilter authenticationTokenFilter; + + /** + * 跨域过滤器 + */ + @Autowired + private CorsFilter corsFilter; + + /** + * 允许匿名访问的地址 + */ + @Autowired + private PermitAllUrlProperties permitAllUrl; + + /** + * 身份验证实现 + */ + @Bean + public AuthenticationManager authenticationManager() + { + DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider(); + daoAuthenticationProvider.setUserDetailsService(userDetailsService); + daoAuthenticationProvider.setPasswordEncoder(bCryptPasswordEncoder()); + return new ProviderManager(daoAuthenticationProvider); + } + + /** + * anyRequest | 匹配所有请求路径 + * access | SpringEl表达式结果为true时可以访问 + * anonymous | 匿名可以访问 + * denyAll | 用户不能访问 + * fullyAuthenticated | 用户完全认证可以访问(非remember-me下自动登录) + * hasAnyAuthority | 如果有参数,参数表示权限,则其中任何一个权限可以访问 + * hasAnyRole | 如果有参数,参数表示角色,则其中任何一个角色可以访问 + * hasAuthority | 如果有参数,参数表示权限,则其权限可以访问 + * hasIpAddress | 如果有参数,参数表示IP地址,如果用户IP和参数匹配,则可以访问 + * hasRole | 如果有参数,参数表示角色,则其角色可以访问 + * permitAll | 用户可以任意访问 + * rememberMe | 允许通过remember-me登录的用户访问 + * authenticated | 用户登录后可访问 + */ + @Bean + protected SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception + { + return httpSecurity + // CSRF禁用,因为不使用session + .csrf(csrf -> csrf.disable()) + // 禁用HTTP响应标头 + .headers((headersCustomizer) -> { + headersCustomizer.cacheControl(cache -> cache.disable()).frameOptions(options -> options.sameOrigin()); + }) + // 认证失败处理类 + .exceptionHandling(exception -> exception.authenticationEntryPoint(unauthorizedHandler)) + // 基于token,所以不需要session + .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) + // 注解标记允许匿名访问的url + .authorizeHttpRequests((requests) -> { + permitAllUrl.getUrls().forEach(url -> requests.antMatchers(url).permitAll()); + // 对于登录login 注册register 验证码captchaImage 允许匿名访问 + requests.antMatchers("/login", "/register", "/captchaImage", "/member/**", "/ws/**").permitAll() + // 静态资源,可匿名访问 + .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll() + .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll() + // 除上面外的所有请求全部需要鉴权认证 + .anyRequest().authenticated(); + }) + // 添加Logout filter + .logout(logout -> logout.logoutUrl("/logout").logoutSuccessHandler(logoutSuccessHandler)) + // 添加JWT filter + .addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class) + // 添加CORS filter + .addFilterBefore(corsFilter, JwtAuthenticationTokenFilter.class) + .addFilterBefore(corsFilter, LogoutFilter.class) + .build(); + } + + /** + * 强散列哈希加密实现 + */ + @Bean + public BCryptPasswordEncoder bCryptPasswordEncoder() + { + return new BCryptPasswordEncoder(); + } +} diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/config/ServerConfig.java b/zzyl-framework/src/main/java/com/zzyl/framework/config/ServerConfig.java new file mode 100644 index 0000000..f8120cf --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/config/ServerConfig.java @@ -0,0 +1,32 @@ +package com.zzyl.framework.config; + +import javax.servlet.http.HttpServletRequest; +import org.springframework.stereotype.Component; +import com.zzyl.common.utils.ServletUtils; + +/** + * 服务相关配置 + * + * @author ruoyi + */ +@Component +public class ServerConfig +{ + /** + * 获取完整的请求路径,包括:域名,端口,上下文访问路径 + * + * @return 服务地址 + */ + public String getUrl() + { + HttpServletRequest request = ServletUtils.getRequest(); + return getDomain(request); + } + + public static String getDomain(HttpServletRequest request) + { + StringBuffer url = request.getRequestURL(); + String contextPath = request.getServletContext().getContextPath(); + return url.delete(url.length() - request.getRequestURI().length(), url.length()).append(contextPath).toString(); + } +} diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/config/ThreadPoolConfig.java b/zzyl-framework/src/main/java/com/zzyl/framework/config/ThreadPoolConfig.java new file mode 100644 index 0000000..7f242fc --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/config/ThreadPoolConfig.java @@ -0,0 +1,63 @@ +package com.zzyl.framework.config; + +import com.zzyl.common.utils.Threads; +import org.apache.commons.lang3.concurrent.BasicThreadFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.ThreadPoolExecutor; + +/** + * 线程池配置 + * + * @author ruoyi + **/ +@Configuration +public class ThreadPoolConfig +{ + // 核心线程池大小 + private int corePoolSize = 50; + + // 最大可创建的线程数 + private int maxPoolSize = 200; + + // 队列最大长度 + private int queueCapacity = 1000; + + // 线程池维护线程所允许的空闲时间 + private int keepAliveSeconds = 300; + + @Bean(name = "threadPoolTaskExecutor") + public ThreadPoolTaskExecutor threadPoolTaskExecutor() + { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + executor.setMaxPoolSize(maxPoolSize); + executor.setCorePoolSize(corePoolSize); + executor.setQueueCapacity(queueCapacity); + executor.setKeepAliveSeconds(keepAliveSeconds); + // 线程池对拒绝任务(无线程可用)的处理策略 + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + return executor; + } + + /** + * 执行周期性或定时任务 + */ + @Bean(name = "scheduledExecutorService") + protected ScheduledExecutorService scheduledExecutorService() + { + return new ScheduledThreadPoolExecutor(corePoolSize, + new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build(), + new ThreadPoolExecutor.CallerRunsPolicy()) + { + @Override + protected void afterExecute(Runnable r, Throwable t) + { + super.afterExecute(r, t); + Threads.printException(r, t); + } + }; + } +} diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/config/properties/DruidProperties.java b/zzyl-framework/src/main/java/com/zzyl/framework/config/properties/DruidProperties.java new file mode 100644 index 0000000..43450f7 --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/config/properties/DruidProperties.java @@ -0,0 +1,89 @@ +package com.zzyl.framework.config.properties; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import com.alibaba.druid.pool.DruidDataSource; + +/** + * druid 配置属性 + * + * @author ruoyi + */ +@Configuration +public class DruidProperties +{ + @Value("${spring.datasource.druid.initialSize}") + private int initialSize; + + @Value("${spring.datasource.druid.minIdle}") + private int minIdle; + + @Value("${spring.datasource.druid.maxActive}") + private int maxActive; + + @Value("${spring.datasource.druid.maxWait}") + private int maxWait; + + @Value("${spring.datasource.druid.connectTimeout}") + private int connectTimeout; + + @Value("${spring.datasource.druid.socketTimeout}") + private int socketTimeout; + + @Value("${spring.datasource.druid.timeBetweenEvictionRunsMillis}") + private int timeBetweenEvictionRunsMillis; + + @Value("${spring.datasource.druid.minEvictableIdleTimeMillis}") + private int minEvictableIdleTimeMillis; + + @Value("${spring.datasource.druid.maxEvictableIdleTimeMillis}") + private int maxEvictableIdleTimeMillis; + + @Value("${spring.datasource.druid.validationQuery}") + private String validationQuery; + + @Value("${spring.datasource.druid.testWhileIdle}") + private boolean testWhileIdle; + + @Value("${spring.datasource.druid.testOnBorrow}") + private boolean testOnBorrow; + + @Value("${spring.datasource.druid.testOnReturn}") + private boolean testOnReturn; + + public DruidDataSource dataSource(DruidDataSource datasource) + { + /** 配置初始化大小、最小、最大 */ + datasource.setInitialSize(initialSize); + datasource.setMaxActive(maxActive); + datasource.setMinIdle(minIdle); + + /** 配置获取连接等待超时的时间 */ + datasource.setMaxWait(maxWait); + + /** 配置驱动连接超时时间,检测数据库建立连接的超时时间,单位是毫秒 */ + datasource.setConnectTimeout(connectTimeout); + + /** 配置网络超时时间,等待数据库操作完成的网络超时时间,单位是毫秒 */ + datasource.setSocketTimeout(socketTimeout); + + /** 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 */ + datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis); + + /** 配置一个连接在池中最小、最大生存的时间,单位是毫秒 */ + datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis); + datasource.setMaxEvictableIdleTimeMillis(maxEvictableIdleTimeMillis); + + /** + * 用来检测连接是否有效的sql,要求是一个查询语句,常用select 'x'。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会起作用。 + */ + datasource.setValidationQuery(validationQuery); + /** 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。 */ + datasource.setTestWhileIdle(testWhileIdle); + /** 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。 */ + datasource.setTestOnBorrow(testOnBorrow); + /** 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。 */ + datasource.setTestOnReturn(testOnReturn); + return datasource; + } +} diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/config/properties/HuaWeiIotConfigProperties.java b/zzyl-framework/src/main/java/com/zzyl/framework/config/properties/HuaWeiIotConfigProperties.java new file mode 100644 index 0000000..f5d21c8 --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/config/properties/HuaWeiIotConfigProperties.java @@ -0,0 +1,107 @@ +package com.zzyl.framework.config.properties; + +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +import java.util.Map; + +/** + * 华为云配置读取 + * + * @author Zhy + * @version 1.0 + * @date 2025-03-05 19:00 + */ +@Data +@NoArgsConstructor +@Configuration +@ConfigurationProperties(prefix = "huaweicloud") +public class HuaWeiIotConfigProperties { + + /** 访问Key */ + private String ak; + + /** 访问秘钥 */ + private String sk; + + /** 区域id */ + private String regionId; + + /** 应用侧https接入地址 */ + private String endpoint; + + /** 项目id */ + private String projectId; + + /** 应用侧amqp接入地址 */ + private String host; + + /** amqp连接端口 */ + private int port = 5671; + + /** amqp接入凭证键值 */ + private String accessKey; + + /** amqp接入凭证密钥 */ + private String accessCode; + + // 指定单个进程启动的连接数 + // 单个连接消费速率有限,请参考使用限制,最大64个连接 + // 连接数和消费速率及rebalance相关,建议每500QPS增加一个连接 + // 可根据实际情况自由调节,目前测试和正式环境资源有限,限制更改为4 + private int connectionCount = 4; + + /** 队列名称 */ + private String queueName; + + /** 开门命令所属服务id */ + private String smartDoorServiceId; + + /** 开门记录属性 */ + private String doorOpenPropertyName; + + /** 开门命令 */ + private String doorOpenCommandName; + + /** 设置临时密码命令 */ + private String passwordSetCommandName; + + /** 仅支持true */ + private boolean useSsl = true; + + /** IoTDA仅支持default */ + private String vhost = "default"; + + /** IoTDA仅支持PLAIN */ + private String saslMechanisms = "PLAIN"; + + /** + * true: SDK自动ACK(默认) + * false:收到消息后,需要手动调用message.acknowledge() + */ + private boolean isAutoAcknowledge = true; + + /** 重连时延(ms) */ + private long reconnectDelay = 3000L; + + /** 最大重连时延(ms),随着重连次数增加重连时延逐渐增加 */ + private long maxReconnectDelay = 30 * 1000L; + + /** 最大重连次数,默认值-1,代表没有限制 */ + private long maxReconnectAttempts = -1; + + /** + * 空闲超时,对端在这个时间段内没有发送AMQP帧则会导致连接断开。默认值为30000。单位:毫秒。 + */ + private long idleTimeout = 30 * 1000L; + + /** + * The values below control how many messages the remote peer can send to the client and be held in a pre-fetch buffer for each consumer instance. + */ + private int queuePrefetch = 1000; + + /** 扩展参数 */ + private Map extendedOptions; +} diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/config/properties/PermitAllUrlProperties.java b/zzyl-framework/src/main/java/com/zzyl/framework/config/properties/PermitAllUrlProperties.java new file mode 100644 index 0000000..fd55589 --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/config/properties/PermitAllUrlProperties.java @@ -0,0 +1,73 @@ +package com.zzyl.framework.config.properties; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.regex.Pattern; +import org.apache.commons.lang3.RegExUtils; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.mvc.method.RequestMappingInfo; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; +import com.zzyl.common.annotation.Anonymous; + +/** + * 设置Anonymous注解允许匿名访问的url + * + * @author ruoyi + */ +@Configuration +public class PermitAllUrlProperties implements InitializingBean, ApplicationContextAware +{ + private static final Pattern PATTERN = Pattern.compile("\\{(.*?)\\}"); + + private ApplicationContext applicationContext; + + private List urls = new ArrayList<>(); + + public String ASTERISK = "*"; + + @Override + public void afterPropertiesSet() + { + RequestMappingHandlerMapping mapping = applicationContext.getBean(RequestMappingHandlerMapping.class); + Map map = mapping.getHandlerMethods(); + + map.keySet().forEach(info -> { + HandlerMethod handlerMethod = map.get(info); + + // 获取方法上边的注解 替代path variable 为 * + Anonymous method = AnnotationUtils.findAnnotation(handlerMethod.getMethod(), Anonymous.class); + Optional.ofNullable(method).ifPresent(anonymous -> Objects.requireNonNull(info.getPatternsCondition().getPatterns()) + .forEach(url -> urls.add(RegExUtils.replaceAll(url, PATTERN, ASTERISK)))); + + // 获取类上边的注解, 替代path variable 为 * + Anonymous controller = AnnotationUtils.findAnnotation(handlerMethod.getBeanType(), Anonymous.class); + Optional.ofNullable(controller).ifPresent(anonymous -> Objects.requireNonNull(info.getPatternsCondition().getPatterns()) + .forEach(url -> urls.add(RegExUtils.replaceAll(url, PATTERN, ASTERISK)))); + }); + } + + @Override + public void setApplicationContext(ApplicationContext context) throws BeansException + { + this.applicationContext = context; + } + + public List getUrls() + { + return urls; + } + + public void setUrls(List urls) + { + this.urls = urls; + } +} diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/datasource/DynamicDataSource.java b/zzyl-framework/src/main/java/com/zzyl/framework/datasource/DynamicDataSource.java new file mode 100644 index 0000000..451cb32 --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/datasource/DynamicDataSource.java @@ -0,0 +1,26 @@ +package com.zzyl.framework.datasource; + +import java.util.Map; +import javax.sql.DataSource; +import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; + +/** + * 动态数据源 + * + * @author ruoyi + */ +public class DynamicDataSource extends AbstractRoutingDataSource +{ + public DynamicDataSource(DataSource defaultTargetDataSource, Map targetDataSources) + { + super.setDefaultTargetDataSource(defaultTargetDataSource); + super.setTargetDataSources(targetDataSources); + super.afterPropertiesSet(); + } + + @Override + protected Object determineCurrentLookupKey() + { + return DynamicDataSourceContextHolder.getDataSourceType(); + } +} \ No newline at end of file diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/datasource/DynamicDataSourceContextHolder.java b/zzyl-framework/src/main/java/com/zzyl/framework/datasource/DynamicDataSourceContextHolder.java new file mode 100644 index 0000000..5ae821d --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/datasource/DynamicDataSourceContextHolder.java @@ -0,0 +1,45 @@ +package com.zzyl.framework.datasource; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * 数据源切换处理 + * + * @author ruoyi + */ +public class DynamicDataSourceContextHolder +{ + public static final Logger log = LoggerFactory.getLogger(DynamicDataSourceContextHolder.class); + + /** + * 使用ThreadLocal维护变量,ThreadLocal为每个使用该变量的线程提供独立的变量副本, + * 所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。 + */ + private static final ThreadLocal CONTEXT_HOLDER = new ThreadLocal<>(); + + /** + * 设置数据源的变量 + */ + public static void setDataSourceType(String dsType) + { + log.info("切换到{}数据源", dsType); + CONTEXT_HOLDER.set(dsType); + } + + /** + * 获得数据源的变量 + */ + public static String getDataSourceType() + { + return CONTEXT_HOLDER.get(); + } + + /** + * 清空数据源变量 + */ + public static void clearDataSourceType() + { + CONTEXT_HOLDER.remove(); + } +} diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/interceptor/MemberInterceptor.java b/zzyl-framework/src/main/java/com/zzyl/framework/interceptor/MemberInterceptor.java new file mode 100644 index 0000000..5d33581 --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/interceptor/MemberInterceptor.java @@ -0,0 +1,76 @@ +package com.zzyl.framework.interceptor; + +import cn.hutool.core.util.ObjUtil; +import cn.hutool.core.util.StrUtil; +import com.zzyl.common.utils.UserThreadLocal; +import com.zzyl.framework.web.service.TokenService; +import io.jsonwebtoken.Claims; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.HandlerInterceptor; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * 自定义拦截器,用于拦截C端请求 + * + * @author Zhy + * @version 1.0 + * @date 2025-03-05 13:21 + */ +@Component +@RequiredArgsConstructor +public class MemberInterceptor implements HandlerInterceptor { + + private final TokenService tokenService; + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + + // 如果不是 Controller 层请求,直接放行 + if (!(handler instanceof HandlerMethod)) { + return true; + } + + // 获取 token + String token = request.getHeader("authorization"); + + // 如果 token 为空,直接返回 401 错误 + if (StrUtil.isEmpty(token)) { + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized"); + return false; + } + + // 解析 token + Claims claims = tokenService.parseToken(token); + if (ObjUtil.isEmpty(claims)) { + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized"); + return false; + } + + // 提取 token 中的数据 + Long userId = claims.get("id", Long.class); + if (ObjUtil.isEmpty(userId)) { + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized"); + return false; + } + + // 将用户 id 放入 ThreadLocal + UserThreadLocal.set(userId); + + return true; + } + + @Override + public void afterCompletion( + HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex + ) { + try { + UserThreadLocal.remove(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/interceptor/MyMetaObjectHandler.java b/zzyl-framework/src/main/java/com/zzyl/framework/interceptor/MyMetaObjectHandler.java new file mode 100644 index 0000000..39995c0 --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/interceptor/MyMetaObjectHandler.java @@ -0,0 +1,77 @@ +package com.zzyl.framework.interceptor; + +import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.zzyl.common.utils.DateUtils; +import com.zzyl.common.utils.SecurityUtils; +import lombok.RequiredArgsConstructor; +import org.apache.ibatis.reflection.MetaObject; +import org.springframework.security.core.Authentication; +import org.springframework.stereotype.Component; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletRequest; +import java.util.Date; + +@Component +@RequiredArgsConstructor +public class MyMetaObjectHandler implements MetaObjectHandler { + + private final HttpServletRequest request; + + /** + * 是否排除路径,排除微信端的路径,不自动填充用户id + * + * @return: + * @param: + */ + private boolean isExclude() { + // 校验是否为 Web 请求,避免非 Web 请求导致 IllegalStateException 异常 + ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + if (attributes != null) { + try { + HttpServletRequest request = attributes.getRequest(); + String path = request.getRequestURI(); + return !path.startsWith("/member"); + } catch (Exception e) { + return true; + } + } + return false; + + // String path = request.getRequestURI(); + // return !path.startsWith("/member"); + } + + // 插入数据时自动填充 + @Override + public void insertFill(MetaObject metaObject) { + if (isExclude()) { + this.strictInsertFill(metaObject, "createBy", String.class, String.valueOf(getLoginUserId())); + } + this.strictInsertFill(metaObject, "createTime", Date.class, DateUtils.getNowDate()); + } + + // 修改数据时自动填充 + @Override + public void updateFill(MetaObject metaObject) { + if (isExclude()) { + this.setFieldValByName("updateBy", String.valueOf(getLoginUserId()), metaObject); + } + this.setFieldValByName("updateTime", DateUtils.getNowDate(), metaObject); + // this.strictUpdateFill(metaObject, "updateBy", String.class, String.valueOf(getLoginUserId())); + // this.strictUpdateFill(metaObject, "updateTime", Date.class, DateUtils.getNowDate()); + } + + // 获取当前登录人的id + public Long getLoginUserId() { + Authentication authentication = SecurityUtils.getAuthentication(); + if (ObjectUtils.isNull(authentication) || ObjectUtils.isNull(authentication.getPrincipal()) || ObjectUtils.isNull( + SecurityUtils.getLoginUser())) { + return 0L; + } + + return SecurityUtils.getLoginUser().getUserId(); + } +} diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/interceptor/RepeatSubmitInterceptor.java b/zzyl-framework/src/main/java/com/zzyl/framework/interceptor/RepeatSubmitInterceptor.java new file mode 100644 index 0000000..19ff5ef --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/interceptor/RepeatSubmitInterceptor.java @@ -0,0 +1,56 @@ +package com.zzyl.framework.interceptor; + +import java.lang.reflect.Method; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.springframework.stereotype.Component; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.HandlerInterceptor; +import com.alibaba.fastjson2.JSON; +import com.zzyl.common.annotation.RepeatSubmit; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.utils.ServletUtils; + +/** + * 防止重复提交拦截器 + * + * @author ruoyi + */ +@Component +public abstract class RepeatSubmitInterceptor implements HandlerInterceptor +{ + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception + { + if (handler instanceof HandlerMethod) + { + HandlerMethod handlerMethod = (HandlerMethod) handler; + Method method = handlerMethod.getMethod(); + RepeatSubmit annotation = method.getAnnotation(RepeatSubmit.class); + if (annotation != null) + { + if (this.isRepeatSubmit(request, annotation)) + { + AjaxResult ajaxResult = AjaxResult.error(annotation.message()); + ServletUtils.renderString(response, JSON.toJSONString(ajaxResult)); + return false; + } + } + return true; + } + else + { + return true; + } + } + + /** + * 验证是否重复提交由子类实现具体的防重复提交的规则 + * + * @param request 请求信息 + * @param annotation 防重复注解参数 + * @return 结果 + * @throws Exception + */ + public abstract boolean isRepeatSubmit(HttpServletRequest request, RepeatSubmit annotation); +} diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/interceptor/impl/SameUrlDataInterceptor.java b/zzyl-framework/src/main/java/com/zzyl/framework/interceptor/impl/SameUrlDataInterceptor.java new file mode 100644 index 0000000..7740fd5 --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/interceptor/impl/SameUrlDataInterceptor.java @@ -0,0 +1,110 @@ +package com.zzyl.framework.interceptor.impl; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import javax.servlet.http.HttpServletRequest; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import com.alibaba.fastjson2.JSON; +import com.zzyl.common.annotation.RepeatSubmit; +import com.zzyl.common.constant.CacheConstants; +import com.zzyl.common.core.redis.RedisCache; +import com.zzyl.common.filter.RepeatedlyRequestWrapper; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.common.utils.http.HttpHelper; +import com.zzyl.framework.interceptor.RepeatSubmitInterceptor; + +/** + * 判断请求url和数据是否和上一次相同, + * 如果和上次相同,则是重复提交表单。 有效时间为10秒内。 + * + * @author ruoyi + */ +@Component +public class SameUrlDataInterceptor extends RepeatSubmitInterceptor +{ + public final String REPEAT_PARAMS = "repeatParams"; + + public final String REPEAT_TIME = "repeatTime"; + + // 令牌自定义标识 + @Value("${token.header}") + private String header; + + @Autowired + private RedisCache redisCache; + + @SuppressWarnings("unchecked") + @Override + public boolean isRepeatSubmit(HttpServletRequest request, RepeatSubmit annotation) + { + String nowParams = ""; + if (request instanceof RepeatedlyRequestWrapper) + { + RepeatedlyRequestWrapper repeatedlyRequest = (RepeatedlyRequestWrapper) request; + nowParams = HttpHelper.getBodyString(repeatedlyRequest); + } + + // body参数为空,获取Parameter的数据 + if (StringUtils.isEmpty(nowParams)) + { + nowParams = JSON.toJSONString(request.getParameterMap()); + } + Map nowDataMap = new HashMap(); + nowDataMap.put(REPEAT_PARAMS, nowParams); + nowDataMap.put(REPEAT_TIME, System.currentTimeMillis()); + + // 请求地址(作为存放cache的key值) + String url = request.getRequestURI(); + + // 唯一值(没有消息头则使用请求地址) + String submitKey = StringUtils.trimToEmpty(request.getHeader(header)); + + // 唯一标识(指定key + url + 消息头) + String cacheRepeatKey = CacheConstants.REPEAT_SUBMIT_KEY + url + submitKey; + + Object sessionObj = redisCache.getCacheObject(cacheRepeatKey); + if (sessionObj != null) + { + Map sessionMap = (Map) sessionObj; + if (sessionMap.containsKey(url)) + { + Map preDataMap = (Map) sessionMap.get(url); + if (compareParams(nowDataMap, preDataMap) && compareTime(nowDataMap, preDataMap, annotation.interval())) + { + return true; + } + } + } + Map cacheMap = new HashMap(); + cacheMap.put(url, nowDataMap); + redisCache.setCacheObject(cacheRepeatKey, cacheMap, annotation.interval(), TimeUnit.MILLISECONDS); + return false; + } + + /** + * 判断参数是否相同 + */ + private boolean compareParams(Map nowMap, Map preMap) + { + String nowParams = (String) nowMap.get(REPEAT_PARAMS); + String preParams = (String) preMap.get(REPEAT_PARAMS); + return nowParams.equals(preParams); + } + + /** + * 判断两次间隔时间 + */ + private boolean compareTime(Map nowMap, Map preMap, int interval) + { + long time1 = (Long) nowMap.get(REPEAT_TIME); + long time2 = (Long) preMap.get(REPEAT_TIME); + if ((time1 - time2) < interval) + { + return true; + } + return false; + } +} diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/manager/AsyncManager.java b/zzyl-framework/src/main/java/com/zzyl/framework/manager/AsyncManager.java new file mode 100644 index 0000000..9bf185d --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/manager/AsyncManager.java @@ -0,0 +1,55 @@ +package com.zzyl.framework.manager; + +import java.util.TimerTask; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import com.zzyl.common.utils.Threads; +import com.zzyl.common.utils.spring.SpringUtils; + +/** + * 异步任务管理器 + * + * @author ruoyi + */ +public class AsyncManager +{ + /** + * 操作延迟10毫秒 + */ + private final int OPERATE_DELAY_TIME = 10; + + /** + * 异步操作任务调度线程池 + */ + private ScheduledExecutorService executor = SpringUtils.getBean("scheduledExecutorService"); + + /** + * 单例模式 + */ + private AsyncManager(){} + + private static AsyncManager me = new AsyncManager(); + + public static AsyncManager me() + { + return me; + } + + /** + * 执行任务 + * + * @param task 任务 + */ + public void execute(TimerTask task) + { + executor.schedule(task, OPERATE_DELAY_TIME, TimeUnit.MILLISECONDS); + } + + /** + * 停止任务线程池 + */ + public void shutdown() + { + Threads.shutdownAndAwaitTermination(executor); + } +} diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/manager/ShutdownManager.java b/zzyl-framework/src/main/java/com/zzyl/framework/manager/ShutdownManager.java new file mode 100644 index 0000000..d027676 --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/manager/ShutdownManager.java @@ -0,0 +1,39 @@ +package com.zzyl.framework.manager; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; +import javax.annotation.PreDestroy; + +/** + * 确保应用退出时能关闭后台线程 + * + * @author ruoyi + */ +@Component +public class ShutdownManager +{ + private static final Logger logger = LoggerFactory.getLogger("sys-user"); + + @PreDestroy + public void destroy() + { + shutdownAsyncManager(); + } + + /** + * 停止异步执行任务 + */ + private void shutdownAsyncManager() + { + try + { + logger.info("====关闭后台任务任务线程池===="); + AsyncManager.me().shutdown(); + } + catch (Exception e) + { + logger.error(e.getMessage(), e); + } + } +} diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/manager/factory/AsyncFactory.java b/zzyl-framework/src/main/java/com/zzyl/framework/manager/factory/AsyncFactory.java new file mode 100644 index 0000000..25f432c --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/manager/factory/AsyncFactory.java @@ -0,0 +1,102 @@ +package com.zzyl.framework.manager.factory; + +import java.util.TimerTask; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.zzyl.common.constant.Constants; +import com.zzyl.common.utils.LogUtils; +import com.zzyl.common.utils.ServletUtils; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.common.utils.ip.AddressUtils; +import com.zzyl.common.utils.ip.IpUtils; +import com.zzyl.common.utils.spring.SpringUtils; +import com.zzyl.system.domain.SysLogininfor; +import com.zzyl.system.domain.SysOperLog; +import com.zzyl.system.service.ISysLogininforService; +import com.zzyl.system.service.ISysOperLogService; +import eu.bitwalker.useragentutils.UserAgent; + +/** + * 异步工厂(产生任务用) + * + * @author ruoyi + */ +public class AsyncFactory +{ + private static final Logger sys_user_logger = LoggerFactory.getLogger("sys-user"); + + /** + * 记录登录信息 + * + * @param username 用户名 + * @param status 状态 + * @param message 消息 + * @param args 列表 + * @return 任务task + */ + public static TimerTask recordLogininfor(final String username, final String status, final String message, + final Object... args) + { + final UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent")); + final String ip = IpUtils.getIpAddr(); + return new TimerTask() + { + @Override + public void run() + { + String address = AddressUtils.getRealAddressByIP(ip); + StringBuilder s = new StringBuilder(); + s.append(LogUtils.getBlock(ip)); + s.append(address); + s.append(LogUtils.getBlock(username)); + s.append(LogUtils.getBlock(status)); + s.append(LogUtils.getBlock(message)); + // 打印信息到日志 + sys_user_logger.info(s.toString(), args); + // 获取客户端操作系统 + String os = userAgent.getOperatingSystem().getName(); + // 获取客户端浏览器 + String browser = userAgent.getBrowser().getName(); + // 封装对象 + SysLogininfor logininfor = new SysLogininfor(); + logininfor.setUserName(username); + logininfor.setIpaddr(ip); + logininfor.setLoginLocation(address); + logininfor.setBrowser(browser); + logininfor.setOs(os); + logininfor.setMsg(message); + // 日志状态 + if (StringUtils.equalsAny(status, Constants.LOGIN_SUCCESS, Constants.LOGOUT, Constants.REGISTER)) + { + logininfor.setStatus(Constants.SUCCESS); + } + else if (Constants.LOGIN_FAIL.equals(status)) + { + logininfor.setStatus(Constants.FAIL); + } + // 插入数据 + SpringUtils.getBean(ISysLogininforService.class).insertLogininfor(logininfor); + } + }; + } + + /** + * 操作日志记录 + * + * @param operLog 操作日志信息 + * @return 任务task + */ + public static TimerTask recordOper(final SysOperLog operLog) + { + return new TimerTask() + { + @Override + public void run() + { + // 远程查询操作地点 + operLog.setOperLocation(AddressUtils.getRealAddressByIP(operLog.getOperIp())); + SpringUtils.getBean(ISysOperLogService.class).insertOperlog(operLog); + } + }; + } +} diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/security/context/AuthenticationContextHolder.java b/zzyl-framework/src/main/java/com/zzyl/framework/security/context/AuthenticationContextHolder.java new file mode 100644 index 0000000..d20a637 --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/security/context/AuthenticationContextHolder.java @@ -0,0 +1,28 @@ +package com.zzyl.framework.security.context; + +import org.springframework.security.core.Authentication; + +/** + * 身份验证信息 + * + * @author ruoyi + */ +public class AuthenticationContextHolder +{ + private static final ThreadLocal contextHolder = new ThreadLocal<>(); + + public static Authentication getContext() + { + return contextHolder.get(); + } + + public static void setContext(Authentication context) + { + contextHolder.set(context); + } + + public static void clearContext() + { + contextHolder.remove(); + } +} diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/security/context/PermissionContextHolder.java b/zzyl-framework/src/main/java/com/zzyl/framework/security/context/PermissionContextHolder.java new file mode 100644 index 0000000..4daa7d3 --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/security/context/PermissionContextHolder.java @@ -0,0 +1,27 @@ +package com.zzyl.framework.security.context; + +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.RequestContextHolder; +import com.zzyl.common.core.text.Convert; + +/** + * 权限信息 + * + * @author ruoyi + */ +public class PermissionContextHolder +{ + private static final String PERMISSION_CONTEXT_ATTRIBUTES = "PERMISSION_CONTEXT"; + + public static void setContext(String permission) + { + RequestContextHolder.currentRequestAttributes().setAttribute(PERMISSION_CONTEXT_ATTRIBUTES, permission, + RequestAttributes.SCOPE_REQUEST); + } + + public static String getContext() + { + return Convert.toStr(RequestContextHolder.currentRequestAttributes().getAttribute(PERMISSION_CONTEXT_ATTRIBUTES, + RequestAttributes.SCOPE_REQUEST)); + } +} diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/security/filter/JwtAuthenticationTokenFilter.java b/zzyl-framework/src/main/java/com/zzyl/framework/security/filter/JwtAuthenticationTokenFilter.java new file mode 100644 index 0000000..11d4fee --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/security/filter/JwtAuthenticationTokenFilter.java @@ -0,0 +1,44 @@ +package com.zzyl.framework.security.filter; + +import java.io.IOException; +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; +import com.zzyl.common.core.domain.model.LoginUser; +import com.zzyl.common.utils.SecurityUtils; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.framework.web.service.TokenService; + +/** + * token过滤器 验证token有效性 + * + * @author ruoyi + */ +@Component +public class JwtAuthenticationTokenFilter extends OncePerRequestFilter +{ + @Autowired + private TokenService tokenService; + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) + throws ServletException, IOException + { + LoginUser loginUser = tokenService.getLoginUser(request); + if (StringUtils.isNotNull(loginUser) && StringUtils.isNull(SecurityUtils.getAuthentication())) + { + tokenService.verifyToken(loginUser); + UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities()); + authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); + SecurityContextHolder.getContext().setAuthentication(authenticationToken); + } + chain.doFilter(request, response); + } +} diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/security/handle/AuthenticationEntryPointImpl.java b/zzyl-framework/src/main/java/com/zzyl/framework/security/handle/AuthenticationEntryPointImpl.java new file mode 100644 index 0000000..b6014ba --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/security/handle/AuthenticationEntryPointImpl.java @@ -0,0 +1,34 @@ +package com.zzyl.framework.security.handle; + +import java.io.IOException; +import java.io.Serializable; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.stereotype.Component; +import com.alibaba.fastjson2.JSON; +import com.zzyl.common.constant.HttpStatus; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.utils.ServletUtils; +import com.zzyl.common.utils.StringUtils; + +/** + * 认证失败处理类 返回未授权 + * + * @author ruoyi + */ +@Component +public class AuthenticationEntryPointImpl implements AuthenticationEntryPoint, Serializable +{ + private static final long serialVersionUID = -8970718410437077606L; + + @Override + public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) + throws IOException + { + int code = HttpStatus.UNAUTHORIZED; + String msg = StringUtils.format("请求访问:{},认证失败,无法访问系统资源", request.getRequestURI()); + ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.error(code, msg))); + } +} diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/security/handle/LogoutSuccessHandlerImpl.java b/zzyl-framework/src/main/java/com/zzyl/framework/security/handle/LogoutSuccessHandlerImpl.java new file mode 100644 index 0000000..d39eeb9 --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/security/handle/LogoutSuccessHandlerImpl.java @@ -0,0 +1,53 @@ +package com.zzyl.framework.security.handle; + +import java.io.IOException; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.core.Authentication; +import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; +import com.alibaba.fastjson2.JSON; +import com.zzyl.common.constant.Constants; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.core.domain.model.LoginUser; +import com.zzyl.common.utils.MessageUtils; +import com.zzyl.common.utils.ServletUtils; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.framework.manager.AsyncManager; +import com.zzyl.framework.manager.factory.AsyncFactory; +import com.zzyl.framework.web.service.TokenService; + +/** + * 自定义退出处理类 返回成功 + * + * @author ruoyi + */ +@Configuration +public class LogoutSuccessHandlerImpl implements LogoutSuccessHandler +{ + @Autowired + private TokenService tokenService; + + /** + * 退出处理 + * + * @return + */ + @Override + public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) + throws IOException, ServletException + { + LoginUser loginUser = tokenService.getLoginUser(request); + if (StringUtils.isNotNull(loginUser)) + { + String userName = loginUser.getUsername(); + // 删除用户缓存记录 + tokenService.delLoginUser(loginUser.getToken()); + // 记录用户退出日志 + AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName, Constants.LOGOUT, MessageUtils.message("user.logout.success"))); + } + ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.success(MessageUtils.message("user.logout.success")))); + } +} diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/web/domain/Server.java b/zzyl-framework/src/main/java/com/zzyl/framework/web/domain/Server.java new file mode 100644 index 0000000..56676b5 --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/web/domain/Server.java @@ -0,0 +1,240 @@ +package com.zzyl.framework.web.domain; + +import java.net.UnknownHostException; +import java.util.LinkedList; +import java.util.List; +import java.util.Properties; +import com.zzyl.common.utils.Arith; +import com.zzyl.common.utils.ip.IpUtils; +import com.zzyl.framework.web.domain.server.Cpu; +import com.zzyl.framework.web.domain.server.Jvm; +import com.zzyl.framework.web.domain.server.Mem; +import com.zzyl.framework.web.domain.server.Sys; +import com.zzyl.framework.web.domain.server.SysFile; +import oshi.SystemInfo; +import oshi.hardware.CentralProcessor; +import oshi.hardware.CentralProcessor.TickType; +import oshi.hardware.GlobalMemory; +import oshi.hardware.HardwareAbstractionLayer; +import oshi.software.os.FileSystem; +import oshi.software.os.OSFileStore; +import oshi.software.os.OperatingSystem; +import oshi.util.Util; + +/** + * 服务器相关信息 + * + * @author ruoyi + */ +public class Server +{ + private static final int OSHI_WAIT_SECOND = 1000; + + /** + * CPU相关信息 + */ + private Cpu cpu = new Cpu(); + + /** + * 內存相关信息 + */ + private Mem mem = new Mem(); + + /** + * JVM相关信息 + */ + private Jvm jvm = new Jvm(); + + /** + * 服务器相关信息 + */ + private Sys sys = new Sys(); + + /** + * 磁盘相关信息 + */ + private List sysFiles = new LinkedList(); + + public Cpu getCpu() + { + return cpu; + } + + public void setCpu(Cpu cpu) + { + this.cpu = cpu; + } + + public Mem getMem() + { + return mem; + } + + public void setMem(Mem mem) + { + this.mem = mem; + } + + public Jvm getJvm() + { + return jvm; + } + + public void setJvm(Jvm jvm) + { + this.jvm = jvm; + } + + public Sys getSys() + { + return sys; + } + + public void setSys(Sys sys) + { + this.sys = sys; + } + + public List getSysFiles() + { + return sysFiles; + } + + public void setSysFiles(List sysFiles) + { + this.sysFiles = sysFiles; + } + + public void copyTo() throws Exception + { + SystemInfo si = new SystemInfo(); + HardwareAbstractionLayer hal = si.getHardware(); + + setCpuInfo(hal.getProcessor()); + + setMemInfo(hal.getMemory()); + + setSysInfo(); + + setJvmInfo(); + + setSysFiles(si.getOperatingSystem()); + } + + /** + * 设置CPU信息 + */ + private void setCpuInfo(CentralProcessor processor) + { + // CPU信息 + long[] prevTicks = processor.getSystemCpuLoadTicks(); + Util.sleep(OSHI_WAIT_SECOND); + long[] ticks = processor.getSystemCpuLoadTicks(); + long nice = ticks[TickType.NICE.getIndex()] - prevTicks[TickType.NICE.getIndex()]; + long irq = ticks[TickType.IRQ.getIndex()] - prevTicks[TickType.IRQ.getIndex()]; + long softirq = ticks[TickType.SOFTIRQ.getIndex()] - prevTicks[TickType.SOFTIRQ.getIndex()]; + long steal = ticks[TickType.STEAL.getIndex()] - prevTicks[TickType.STEAL.getIndex()]; + long cSys = ticks[TickType.SYSTEM.getIndex()] - prevTicks[TickType.SYSTEM.getIndex()]; + long user = ticks[TickType.USER.getIndex()] - prevTicks[TickType.USER.getIndex()]; + long iowait = ticks[TickType.IOWAIT.getIndex()] - prevTicks[TickType.IOWAIT.getIndex()]; + long idle = ticks[TickType.IDLE.getIndex()] - prevTicks[TickType.IDLE.getIndex()]; + long totalCpu = user + nice + cSys + idle + iowait + irq + softirq + steal; + cpu.setCpuNum(processor.getLogicalProcessorCount()); + cpu.setTotal(totalCpu); + cpu.setSys(cSys); + cpu.setUsed(user); + cpu.setWait(iowait); + cpu.setFree(idle); + } + + /** + * 设置内存信息 + */ + private void setMemInfo(GlobalMemory memory) + { + mem.setTotal(memory.getTotal()); + mem.setUsed(memory.getTotal() - memory.getAvailable()); + mem.setFree(memory.getAvailable()); + } + + /** + * 设置服务器信息 + */ + private void setSysInfo() + { + Properties props = System.getProperties(); + sys.setComputerName(IpUtils.getHostName()); + sys.setComputerIp(IpUtils.getHostIp()); + sys.setOsName(props.getProperty("os.name")); + sys.setOsArch(props.getProperty("os.arch")); + sys.setUserDir(props.getProperty("user.dir")); + } + + /** + * 设置Java虚拟机 + */ + private void setJvmInfo() throws UnknownHostException + { + Properties props = System.getProperties(); + jvm.setTotal(Runtime.getRuntime().totalMemory()); + jvm.setMax(Runtime.getRuntime().maxMemory()); + jvm.setFree(Runtime.getRuntime().freeMemory()); + jvm.setVersion(props.getProperty("java.version")); + jvm.setHome(props.getProperty("java.home")); + } + + /** + * 设置磁盘信息 + */ + private void setSysFiles(OperatingSystem os) + { + FileSystem fileSystem = os.getFileSystem(); + List fsArray = fileSystem.getFileStores(); + for (OSFileStore fs : fsArray) + { + long free = fs.getUsableSpace(); + long total = fs.getTotalSpace(); + long used = total - free; + SysFile sysFile = new SysFile(); + sysFile.setDirName(fs.getMount()); + sysFile.setSysTypeName(fs.getType()); + sysFile.setTypeName(fs.getName()); + sysFile.setTotal(convertFileSize(total)); + sysFile.setFree(convertFileSize(free)); + sysFile.setUsed(convertFileSize(used)); + sysFile.setUsage(Arith.mul(Arith.div(used, total, 4), 100)); + sysFiles.add(sysFile); + } + } + + /** + * 字节转换 + * + * @param size 字节大小 + * @return 转换后值 + */ + public String convertFileSize(long size) + { + long kb = 1024; + long mb = kb * 1024; + long gb = mb * 1024; + if (size >= gb) + { + return String.format("%.1f GB", (float) size / gb); + } + else if (size >= mb) + { + float f = (float) size / mb; + return String.format(f > 100 ? "%.0f MB" : "%.1f MB", f); + } + else if (size >= kb) + { + float f = (float) size / kb; + return String.format(f > 100 ? "%.0f KB" : "%.1f KB", f); + } + else + { + return String.format("%d B", size); + } + } +} diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/web/domain/server/Cpu.java b/zzyl-framework/src/main/java/com/zzyl/framework/web/domain/server/Cpu.java new file mode 100644 index 0000000..e0a3018 --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/web/domain/server/Cpu.java @@ -0,0 +1,101 @@ +package com.zzyl.framework.web.domain.server; + +import com.zzyl.common.utils.Arith; + +/** + * CPU相关信息 + * + * @author ruoyi + */ +public class Cpu +{ + /** + * 核心数 + */ + private int cpuNum; + + /** + * CPU总的使用率 + */ + private double total; + + /** + * CPU系统使用率 + */ + private double sys; + + /** + * CPU用户使用率 + */ + private double used; + + /** + * CPU当前等待率 + */ + private double wait; + + /** + * CPU当前空闲率 + */ + private double free; + + public int getCpuNum() + { + return cpuNum; + } + + public void setCpuNum(int cpuNum) + { + this.cpuNum = cpuNum; + } + + public double getTotal() + { + return Arith.round(Arith.mul(total, 100), 2); + } + + public void setTotal(double total) + { + this.total = total; + } + + public double getSys() + { + return Arith.round(Arith.mul(sys / total, 100), 2); + } + + public void setSys(double sys) + { + this.sys = sys; + } + + public double getUsed() + { + return Arith.round(Arith.mul(used / total, 100), 2); + } + + public void setUsed(double used) + { + this.used = used; + } + + public double getWait() + { + return Arith.round(Arith.mul(wait / total, 100), 2); + } + + public void setWait(double wait) + { + this.wait = wait; + } + + public double getFree() + { + return Arith.round(Arith.mul(free / total, 100), 2); + } + + public void setFree(double free) + { + this.free = free; + } +} diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/web/domain/server/Jvm.java b/zzyl-framework/src/main/java/com/zzyl/framework/web/domain/server/Jvm.java new file mode 100644 index 0000000..f8ad1f4 --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/web/domain/server/Jvm.java @@ -0,0 +1,130 @@ +package com.zzyl.framework.web.domain.server; + +import java.lang.management.ManagementFactory; +import com.zzyl.common.utils.Arith; +import com.zzyl.common.utils.DateUtils; + +/** + * JVM相关信息 + * + * @author ruoyi + */ +public class Jvm +{ + /** + * 当前JVM占用的内存总数(M) + */ + private double total; + + /** + * JVM最大可用内存总数(M) + */ + private double max; + + /** + * JVM空闲内存(M) + */ + private double free; + + /** + * JDK版本 + */ + private String version; + + /** + * JDK路径 + */ + private String home; + + public double getTotal() + { + return Arith.div(total, (1024 * 1024), 2); + } + + public void setTotal(double total) + { + this.total = total; + } + + public double getMax() + { + return Arith.div(max, (1024 * 1024), 2); + } + + public void setMax(double max) + { + this.max = max; + } + + public double getFree() + { + return Arith.div(free, (1024 * 1024), 2); + } + + public void setFree(double free) + { + this.free = free; + } + + public double getUsed() + { + return Arith.div(total - free, (1024 * 1024), 2); + } + + public double getUsage() + { + return Arith.mul(Arith.div(total - free, total, 4), 100); + } + + /** + * 获取JDK名称 + */ + public String getName() + { + return ManagementFactory.getRuntimeMXBean().getVmName(); + } + + public String getVersion() + { + return version; + } + + public void setVersion(String version) + { + this.version = version; + } + + public String getHome() + { + return home; + } + + public void setHome(String home) + { + this.home = home; + } + + /** + * JDK启动时间 + */ + public String getStartTime() + { + return DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, DateUtils.getServerStartDate()); + } + + /** + * JDK运行时间 + */ + public String getRunTime() + { + return DateUtils.timeDistance(DateUtils.getNowDate(), DateUtils.getServerStartDate()); + } + + /** + * 运行参数 + */ + public String getInputArgs() + { + return ManagementFactory.getRuntimeMXBean().getInputArguments().toString(); + } +} diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/web/domain/server/Mem.java b/zzyl-framework/src/main/java/com/zzyl/framework/web/domain/server/Mem.java new file mode 100644 index 0000000..e21056b --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/web/domain/server/Mem.java @@ -0,0 +1,61 @@ +package com.zzyl.framework.web.domain.server; + +import com.zzyl.common.utils.Arith; + +/** + * 內存相关信息 + * + * @author ruoyi + */ +public class Mem +{ + /** + * 内存总量 + */ + private double total; + + /** + * 已用内存 + */ + private double used; + + /** + * 剩余内存 + */ + private double free; + + public double getTotal() + { + return Arith.div(total, (1024 * 1024 * 1024), 2); + } + + public void setTotal(long total) + { + this.total = total; + } + + public double getUsed() + { + return Arith.div(used, (1024 * 1024 * 1024), 2); + } + + public void setUsed(long used) + { + this.used = used; + } + + public double getFree() + { + return Arith.div(free, (1024 * 1024 * 1024), 2); + } + + public void setFree(long free) + { + this.free = free; + } + + public double getUsage() + { + return Arith.mul(Arith.div(used, total, 4), 100); + } +} diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/web/domain/server/Sys.java b/zzyl-framework/src/main/java/com/zzyl/framework/web/domain/server/Sys.java new file mode 100644 index 0000000..f390df8 --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/web/domain/server/Sys.java @@ -0,0 +1,84 @@ +package com.zzyl.framework.web.domain.server; + +/** + * 系统相关信息 + * + * @author ruoyi + */ +public class Sys +{ + /** + * 服务器名称 + */ + private String computerName; + + /** + * 服务器Ip + */ + private String computerIp; + + /** + * 项目路径 + */ + private String userDir; + + /** + * 操作系统 + */ + private String osName; + + /** + * 系统架构 + */ + private String osArch; + + public String getComputerName() + { + return computerName; + } + + public void setComputerName(String computerName) + { + this.computerName = computerName; + } + + public String getComputerIp() + { + return computerIp; + } + + public void setComputerIp(String computerIp) + { + this.computerIp = computerIp; + } + + public String getUserDir() + { + return userDir; + } + + public void setUserDir(String userDir) + { + this.userDir = userDir; + } + + public String getOsName() + { + return osName; + } + + public void setOsName(String osName) + { + this.osName = osName; + } + + public String getOsArch() + { + return osArch; + } + + public void setOsArch(String osArch) + { + this.osArch = osArch; + } +} diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/web/domain/server/SysFile.java b/zzyl-framework/src/main/java/com/zzyl/framework/web/domain/server/SysFile.java new file mode 100644 index 0000000..d917d76 --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/web/domain/server/SysFile.java @@ -0,0 +1,114 @@ +package com.zzyl.framework.web.domain.server; + +/** + * 系统文件相关信息 + * + * @author ruoyi + */ +public class SysFile +{ + /** + * 盘符路径 + */ + private String dirName; + + /** + * 盘符类型 + */ + private String sysTypeName; + + /** + * 文件类型 + */ + private String typeName; + + /** + * 总大小 + */ + private String total; + + /** + * 剩余大小 + */ + private String free; + + /** + * 已经使用量 + */ + private String used; + + /** + * 资源的使用率 + */ + private double usage; + + public String getDirName() + { + return dirName; + } + + public void setDirName(String dirName) + { + this.dirName = dirName; + } + + public String getSysTypeName() + { + return sysTypeName; + } + + public void setSysTypeName(String sysTypeName) + { + this.sysTypeName = sysTypeName; + } + + public String getTypeName() + { + return typeName; + } + + public void setTypeName(String typeName) + { + this.typeName = typeName; + } + + public String getTotal() + { + return total; + } + + public void setTotal(String total) + { + this.total = total; + } + + public String getFree() + { + return free; + } + + public void setFree(String free) + { + this.free = free; + } + + public String getUsed() + { + return used; + } + + public void setUsed(String used) + { + this.used = used; + } + + public double getUsage() + { + return usage; + } + + public void setUsage(double usage) + { + this.usage = usage; + } +} diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/web/exception/GlobalExceptionHandler.java b/zzyl-framework/src/main/java/com/zzyl/framework/web/exception/GlobalExceptionHandler.java new file mode 100644 index 0000000..b70f341 --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/web/exception/GlobalExceptionHandler.java @@ -0,0 +1,145 @@ +package com.zzyl.framework.web.exception; + +import javax.servlet.http.HttpServletRequest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.validation.BindException; +import org.springframework.web.HttpRequestMethodNotSupportedException; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.MissingPathVariableException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; +import com.zzyl.common.constant.HttpStatus; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.core.text.Convert; +import com.zzyl.common.exception.DemoModeException; +import com.zzyl.common.exception.ServiceException; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.common.utils.html.EscapeUtil; + +/** + * 全局异常处理器 + * + * @author ruoyi + */ +@RestControllerAdvice +public class GlobalExceptionHandler +{ + private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class); + + /** + * 权限校验异常 + */ + @ExceptionHandler(AccessDeniedException.class) + public AjaxResult handleAccessDeniedException(AccessDeniedException e, HttpServletRequest request) + { + String requestURI = request.getRequestURI(); + log.error("请求地址'{}',权限校验失败'{}'", requestURI, e.getMessage()); + return AjaxResult.error(HttpStatus.FORBIDDEN, "没有权限,请联系管理员授权"); + } + + /** + * 请求方式不支持 + */ + @ExceptionHandler(HttpRequestMethodNotSupportedException.class) + public AjaxResult handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e, + HttpServletRequest request) + { + String requestURI = request.getRequestURI(); + log.error("请求地址'{}',不支持'{}'请求", requestURI, e.getMethod()); + return AjaxResult.error(e.getMessage()); + } + + /** + * 业务异常 + */ + @ExceptionHandler(ServiceException.class) + public AjaxResult handleServiceException(ServiceException e, HttpServletRequest request) + { + log.error(e.getMessage(), e); + Integer code = e.getCode(); + return StringUtils.isNotNull(code) ? AjaxResult.error(code, e.getMessage()) : AjaxResult.error(e.getMessage()); + } + + /** + * 请求路径中缺少必需的路径变量 + */ + @ExceptionHandler(MissingPathVariableException.class) + public AjaxResult handleMissingPathVariableException(MissingPathVariableException e, HttpServletRequest request) + { + String requestURI = request.getRequestURI(); + log.error("请求路径中缺少必需的路径变量'{}',发生系统异常.", requestURI, e); + return AjaxResult.error(String.format("请求路径中缺少必需的路径变量[%s]", e.getVariableName())); + } + + /** + * 请求参数类型不匹配 + */ + @ExceptionHandler(MethodArgumentTypeMismatchException.class) + public AjaxResult handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e, HttpServletRequest request) + { + String requestURI = request.getRequestURI(); + String value = Convert.toStr(e.getValue()); + if (StringUtils.isNotEmpty(value)) + { + value = EscapeUtil.clean(value); + } + log.error("请求参数类型不匹配'{}',发生系统异常.", requestURI, e); + return AjaxResult.error(String.format("请求参数类型不匹配,参数[%s]要求类型为:'%s',但输入值为:'%s'", e.getName(), e.getRequiredType().getName(), value)); + } + + /** + * 拦截未知的运行时异常 + */ + @ExceptionHandler(RuntimeException.class) + public AjaxResult handleRuntimeException(RuntimeException e, HttpServletRequest request) + { + String requestURI = request.getRequestURI(); + log.error("请求地址'{}',发生未知异常.", requestURI, e); + return AjaxResult.error(e.getMessage()); + } + + /** + * 系统异常 + */ + @ExceptionHandler(Exception.class) + public AjaxResult handleException(Exception e, HttpServletRequest request) + { + String requestURI = request.getRequestURI(); + log.error("请求地址'{}',发生系统异常.", requestURI, e); + return AjaxResult.error(e.getMessage()); + } + + /** + * 自定义验证异常 + */ + @ExceptionHandler(BindException.class) + public AjaxResult handleBindException(BindException e) + { + log.error(e.getMessage(), e); + String message = e.getAllErrors().get(0).getDefaultMessage(); + return AjaxResult.error(message); + } + + /** + * 自定义验证异常 + */ + @ExceptionHandler(MethodArgumentNotValidException.class) + public Object handleMethodArgumentNotValidException(MethodArgumentNotValidException e) + { + log.error(e.getMessage(), e); + String message = e.getBindingResult().getFieldError().getDefaultMessage(); + return AjaxResult.error(message); + } + + /** + * 演示模式异常 + */ + @ExceptionHandler(DemoModeException.class) + public AjaxResult handleDemoModeException(DemoModeException e) + { + return AjaxResult.error("演示模式,不允许操作"); + } +} diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/web/service/PermissionService.java b/zzyl-framework/src/main/java/com/zzyl/framework/web/service/PermissionService.java new file mode 100644 index 0000000..8301ce9 --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/web/service/PermissionService.java @@ -0,0 +1,159 @@ +package com.zzyl.framework.web.service; + +import java.util.Set; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import com.zzyl.common.constant.Constants; +import com.zzyl.common.core.domain.entity.SysRole; +import com.zzyl.common.core.domain.model.LoginUser; +import com.zzyl.common.utils.SecurityUtils; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.framework.security.context.PermissionContextHolder; + +/** + * RuoYi首创 自定义权限实现,ss取自SpringSecurity首字母 + * + * @author ruoyi + */ +@Service("ss") +public class PermissionService +{ + /** + * 验证用户是否具备某权限 + * + * @param permission 权限字符串 + * @return 用户是否具备某权限 + */ + public boolean hasPermi(String permission) + { + if (StringUtils.isEmpty(permission)) + { + return false; + } + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getPermissions())) + { + return false; + } + PermissionContextHolder.setContext(permission); + return hasPermissions(loginUser.getPermissions(), permission); + } + + /** + * 验证用户是否不具备某权限,与 hasPermi逻辑相反 + * + * @param permission 权限字符串 + * @return 用户是否不具备某权限 + */ + public boolean lacksPermi(String permission) + { + return hasPermi(permission) != true; + } + + /** + * 验证用户是否具有以下任意一个权限 + * + * @param permissions 以 PERMISSION_DELIMETER 为分隔符的权限列表 + * @return 用户是否具有以下任意一个权限 + */ + public boolean hasAnyPermi(String permissions) + { + if (StringUtils.isEmpty(permissions)) + { + return false; + } + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getPermissions())) + { + return false; + } + PermissionContextHolder.setContext(permissions); + Set authorities = loginUser.getPermissions(); + for (String permission : permissions.split(Constants.PERMISSION_DELIMETER)) + { + if (permission != null && hasPermissions(authorities, permission)) + { + return true; + } + } + return false; + } + + /** + * 判断用户是否拥有某个角色 + * + * @param role 角色字符串 + * @return 用户是否具备某角色 + */ + public boolean hasRole(String role) + { + if (StringUtils.isEmpty(role)) + { + return false; + } + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getUser().getRoles())) + { + return false; + } + for (SysRole sysRole : loginUser.getUser().getRoles()) + { + String roleKey = sysRole.getRoleKey(); + if (Constants.SUPER_ADMIN.equals(roleKey) || roleKey.equals(StringUtils.trim(role))) + { + return true; + } + } + return false; + } + + /** + * 验证用户是否不具备某角色,与 isRole逻辑相反。 + * + * @param role 角色名称 + * @return 用户是否不具备某角色 + */ + public boolean lacksRole(String role) + { + return hasRole(role) != true; + } + + /** + * 验证用户是否具有以下任意一个角色 + * + * @param roles 以 ROLE_NAMES_DELIMETER 为分隔符的角色列表 + * @return 用户是否具有以下任意一个角色 + */ + public boolean hasAnyRoles(String roles) + { + if (StringUtils.isEmpty(roles)) + { + return false; + } + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getUser().getRoles())) + { + return false; + } + for (String role : roles.split(Constants.ROLE_DELIMETER)) + { + if (hasRole(role)) + { + return true; + } + } + return false; + } + + /** + * 判断是否包含权限 + * + * @param permissions 权限列表 + * @param permission 权限字符串 + * @return 用户是否具备某权限 + */ + private boolean hasPermissions(Set permissions, String permission) + { + return permissions.contains(Constants.ALL_PERMISSION) || permissions.contains(StringUtils.trim(permission)); + } +} diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/web/service/SysLoginService.java b/zzyl-framework/src/main/java/com/zzyl/framework/web/service/SysLoginService.java new file mode 100644 index 0000000..2f0a1cc --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/web/service/SysLoginService.java @@ -0,0 +1,181 @@ +package com.zzyl.framework.web.service; + +import javax.annotation.Resource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.stereotype.Component; +import com.zzyl.common.constant.CacheConstants; +import com.zzyl.common.constant.Constants; +import com.zzyl.common.constant.UserConstants; +import com.zzyl.common.core.domain.entity.SysUser; +import com.zzyl.common.core.domain.model.LoginUser; +import com.zzyl.common.core.redis.RedisCache; +import com.zzyl.common.exception.ServiceException; +import com.zzyl.common.exception.user.BlackListException; +import com.zzyl.common.exception.user.CaptchaException; +import com.zzyl.common.exception.user.CaptchaExpireException; +import com.zzyl.common.exception.user.UserNotExistsException; +import com.zzyl.common.exception.user.UserPasswordNotMatchException; +import com.zzyl.common.utils.DateUtils; +import com.zzyl.common.utils.MessageUtils; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.common.utils.ip.IpUtils; +import com.zzyl.framework.manager.AsyncManager; +import com.zzyl.framework.manager.factory.AsyncFactory; +import com.zzyl.framework.security.context.AuthenticationContextHolder; +import com.zzyl.system.service.ISysConfigService; +import com.zzyl.system.service.ISysUserService; + +/** + * 登录校验方法 + * + * @author ruoyi + */ +@Component +public class SysLoginService +{ + @Autowired + private TokenService tokenService; + + @Resource + private AuthenticationManager authenticationManager; + + @Autowired + private RedisCache redisCache; + + @Autowired + private ISysUserService userService; + + @Autowired + private ISysConfigService configService; + + /** + * 登录验证 + * + * @param username 用户名 + * @param password 密码 + * @param code 验证码 + * @param uuid 唯一标识 + * @return 结果 + */ + public String login(String username, String password, String code, String uuid) + { + // 验证码校验 + validateCaptcha(username, code, uuid); + // 登录前置校验 + loginPreCheck(username, password); + // 用户验证 + Authentication authentication = null; + try + { + UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password); + AuthenticationContextHolder.setContext(authenticationToken); + // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername + authentication = authenticationManager.authenticate(authenticationToken); + } + catch (Exception e) + { + if (e instanceof BadCredentialsException) + { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match"))); + throw new UserPasswordNotMatchException(); + } + else + { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage())); + throw new ServiceException(e.getMessage()); + } + } + finally + { + AuthenticationContextHolder.clearContext(); + } + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"))); + LoginUser loginUser = (LoginUser) authentication.getPrincipal(); + recordLoginInfo(loginUser.getUserId()); + // 生成token + return tokenService.createToken(loginUser); + } + + /** + * 校验验证码 + * + * @param username 用户名 + * @param code 验证码 + * @param uuid 唯一标识 + * @return 结果 + */ + public void validateCaptcha(String username, String code, String uuid) + { + boolean captchaEnabled = configService.selectCaptchaEnabled(); + if (captchaEnabled) + { + String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, ""); + String captcha = redisCache.getCacheObject(verifyKey); + if (captcha == null) + { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"))); + throw new CaptchaExpireException(); + } + redisCache.deleteObject(verifyKey); + if (!code.equalsIgnoreCase(captcha)) + { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error"))); + throw new CaptchaException(); + } + } + } + + /** + * 登录前置校验 + * @param username 用户名 + * @param password 用户密码 + */ + public void loginPreCheck(String username, String password) + { + // 用户名或密码为空 错误 + if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) + { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("not.null"))); + throw new UserNotExistsException(); + } + // 密码如果不在指定范围内 错误 + if (password.length() < UserConstants.PASSWORD_MIN_LENGTH + || password.length() > UserConstants.PASSWORD_MAX_LENGTH) + { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match"))); + throw new UserPasswordNotMatchException(); + } + // 用户名不在指定范围内 错误 + if (username.length() < UserConstants.USERNAME_MIN_LENGTH + || username.length() > UserConstants.USERNAME_MAX_LENGTH) + { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match"))); + throw new UserPasswordNotMatchException(); + } + // IP黑名单校验 + String blackStr = configService.selectConfigByKey("sys.login.blackIPList"); + if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr())) + { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("login.blocked"))); + throw new BlackListException(); + } + } + + /** + * 记录登录信息 + * + * @param userId 用户ID + */ + public void recordLoginInfo(Long userId) + { + SysUser sysUser = new SysUser(); + sysUser.setUserId(userId); + sysUser.setLoginIp(IpUtils.getIpAddr()); + sysUser.setLoginDate(DateUtils.getNowDate()); + userService.updateUserProfile(sysUser); + } +} diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/web/service/SysPasswordService.java b/zzyl-framework/src/main/java/com/zzyl/framework/web/service/SysPasswordService.java new file mode 100644 index 0000000..8b21540 --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/web/service/SysPasswordService.java @@ -0,0 +1,86 @@ +package com.zzyl.framework.web.service; + +import java.util.concurrent.TimeUnit; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.core.Authentication; +import org.springframework.stereotype.Component; +import com.zzyl.common.constant.CacheConstants; +import com.zzyl.common.core.domain.entity.SysUser; +import com.zzyl.common.core.redis.RedisCache; +import com.zzyl.common.exception.user.UserPasswordNotMatchException; +import com.zzyl.common.exception.user.UserPasswordRetryLimitExceedException; +import com.zzyl.common.utils.SecurityUtils; +import com.zzyl.framework.security.context.AuthenticationContextHolder; + +/** + * 登录密码方法 + * + * @author ruoyi + */ +@Component +public class SysPasswordService +{ + @Autowired + private RedisCache redisCache; + + @Value(value = "${user.password.maxRetryCount}") + private int maxRetryCount; + + @Value(value = "${user.password.lockTime}") + private int lockTime; + + /** + * 登录账户密码错误次数缓存键名 + * + * @param username 用户名 + * @return 缓存键key + */ + private String getCacheKey(String username) + { + return CacheConstants.PWD_ERR_CNT_KEY + username; + } + + public void validate(SysUser user) + { + Authentication usernamePasswordAuthenticationToken = AuthenticationContextHolder.getContext(); + String username = usernamePasswordAuthenticationToken.getName(); + String password = usernamePasswordAuthenticationToken.getCredentials().toString(); + + Integer retryCount = redisCache.getCacheObject(getCacheKey(username)); + + if (retryCount == null) + { + retryCount = 0; + } + + if (retryCount >= Integer.valueOf(maxRetryCount).intValue()) + { + throw new UserPasswordRetryLimitExceedException(maxRetryCount, lockTime); + } + + if (!matches(user, password)) + { + retryCount = retryCount + 1; + redisCache.setCacheObject(getCacheKey(username), retryCount, lockTime, TimeUnit.MINUTES); + throw new UserPasswordNotMatchException(); + } + else + { + clearLoginRecordCache(username); + } + } + + public boolean matches(SysUser user, String rawPassword) + { + return SecurityUtils.matchesPassword(rawPassword, user.getPassword()); + } + + public void clearLoginRecordCache(String loginName) + { + if (redisCache.hasKey(getCacheKey(loginName))) + { + redisCache.deleteObject(getCacheKey(loginName)); + } + } +} diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/web/service/SysPermissionService.java b/zzyl-framework/src/main/java/com/zzyl/framework/web/service/SysPermissionService.java new file mode 100644 index 0000000..a816191 --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/web/service/SysPermissionService.java @@ -0,0 +1,88 @@ +package com.zzyl.framework.web.service; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; +import com.zzyl.common.constant.UserConstants; +import com.zzyl.common.core.domain.entity.SysRole; +import com.zzyl.common.core.domain.entity.SysUser; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.system.service.ISysMenuService; +import com.zzyl.system.service.ISysRoleService; + +/** + * 用户权限处理 + * + * @author ruoyi + */ +@Component +public class SysPermissionService +{ + @Autowired + private ISysRoleService roleService; + + @Autowired + private ISysMenuService menuService; + + /** + * 获取角色数据权限 + * + * @param user 用户信息 + * @return 角色权限信息 + */ + public Set getRolePermission(SysUser user) + { + Set roles = new HashSet(); + // 管理员拥有所有权限 + if (user.isAdmin()) + { + roles.add("admin"); + } + else + { + roles.addAll(roleService.selectRolePermissionByUserId(user.getUserId())); + } + return roles; + } + + /** + * 获取菜单数据权限 + * + * @param user 用户信息 + * @return 菜单权限信息 + */ + public Set getMenuPermission(SysUser user) + { + Set perms = new HashSet(); + // 管理员拥有所有权限 + if (user.isAdmin()) + { + perms.add("*:*:*"); + } + else + { + List roles = user.getRoles(); + if (!CollectionUtils.isEmpty(roles)) + { + // 多角色设置permissions属性,以便数据权限匹配权限 + for (SysRole role : roles) + { + if (StringUtils.equals(role.getStatus(), UserConstants.ROLE_NORMAL)) + { + Set rolePerms = menuService.selectMenuPermsByRoleId(role.getRoleId()); + role.setPermissions(rolePerms); + perms.addAll(rolePerms); + } + } + } + else + { + perms.addAll(menuService.selectMenuPermsByUserId(user.getUserId())); + } + } + return perms; + } +} diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/web/service/SysRegisterService.java b/zzyl-framework/src/main/java/com/zzyl/framework/web/service/SysRegisterService.java new file mode 100644 index 0000000..67ae0be --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/web/service/SysRegisterService.java @@ -0,0 +1,115 @@ +package com.zzyl.framework.web.service; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import com.zzyl.common.constant.CacheConstants; +import com.zzyl.common.constant.Constants; +import com.zzyl.common.constant.UserConstants; +import com.zzyl.common.core.domain.entity.SysUser; +import com.zzyl.common.core.domain.model.RegisterBody; +import com.zzyl.common.core.redis.RedisCache; +import com.zzyl.common.exception.user.CaptchaException; +import com.zzyl.common.exception.user.CaptchaExpireException; +import com.zzyl.common.utils.MessageUtils; +import com.zzyl.common.utils.SecurityUtils; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.framework.manager.AsyncManager; +import com.zzyl.framework.manager.factory.AsyncFactory; +import com.zzyl.system.service.ISysConfigService; +import com.zzyl.system.service.ISysUserService; + +/** + * 注册校验方法 + * + * @author ruoyi + */ +@Component +public class SysRegisterService +{ + @Autowired + private ISysUserService userService; + + @Autowired + private ISysConfigService configService; + + @Autowired + private RedisCache redisCache; + + /** + * 注册 + */ + public String register(RegisterBody registerBody) + { + String msg = "", username = registerBody.getUsername(), password = registerBody.getPassword(); + SysUser sysUser = new SysUser(); + sysUser.setUserName(username); + + // 验证码开关 + boolean captchaEnabled = configService.selectCaptchaEnabled(); + if (captchaEnabled) + { + validateCaptcha(username, registerBody.getCode(), registerBody.getUuid()); + } + + if (StringUtils.isEmpty(username)) + { + msg = "用户名不能为空"; + } + else if (StringUtils.isEmpty(password)) + { + msg = "用户密码不能为空"; + } + else if (username.length() < UserConstants.USERNAME_MIN_LENGTH + || username.length() > UserConstants.USERNAME_MAX_LENGTH) + { + msg = "账户长度必须在2到20个字符之间"; + } + else if (password.length() < UserConstants.PASSWORD_MIN_LENGTH + || password.length() > UserConstants.PASSWORD_MAX_LENGTH) + { + msg = "密码长度必须在5到20个字符之间"; + } + else if (!userService.checkUserNameUnique(sysUser)) + { + msg = "保存用户'" + username + "'失败,注册账号已存在"; + } + else + { + sysUser.setNickName(username); + sysUser.setPassword(SecurityUtils.encryptPassword(password)); + boolean regFlag = userService.registerUser(sysUser); + if (!regFlag) + { + msg = "注册失败,请联系系统管理人员"; + } + else + { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.REGISTER, MessageUtils.message("user.register.success"))); + } + } + return msg; + } + + /** + * 校验验证码 + * + * @param username 用户名 + * @param code 验证码 + * @param uuid 唯一标识 + * @return 结果 + */ + public void validateCaptcha(String username, String code, String uuid) + { + String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, ""); + String captcha = redisCache.getCacheObject(verifyKey); + redisCache.deleteObject(verifyKey); + if (captcha == null) + { + throw new CaptchaExpireException(); + } + if (!code.equalsIgnoreCase(captcha)) + { + throw new CaptchaException(); + } + } +} diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/web/service/TokenService.java b/zzyl-framework/src/main/java/com/zzyl/framework/web/service/TokenService.java new file mode 100644 index 0000000..970716b --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/web/service/TokenService.java @@ -0,0 +1,231 @@ +package com.zzyl.framework.web.service; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import javax.servlet.http.HttpServletRequest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import com.zzyl.common.constant.CacheConstants; +import com.zzyl.common.constant.Constants; +import com.zzyl.common.core.domain.model.LoginUser; +import com.zzyl.common.core.redis.RedisCache; +import com.zzyl.common.utils.ServletUtils; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.common.utils.ip.AddressUtils; +import com.zzyl.common.utils.ip.IpUtils; +import com.zzyl.common.utils.uuid.IdUtils; +import eu.bitwalker.useragentutils.UserAgent; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; + +/** + * token验证处理 + * + * @author ruoyi + */ +@Component +public class TokenService +{ + private static final Logger log = LoggerFactory.getLogger(TokenService.class); + + // 令牌自定义标识 + @Value("${token.header}") + private String header; + + // 令牌秘钥 + @Value("${token.secret}") + private String secret; + + // 令牌有效期(默认30分钟) + @Value("${token.expireTime}") + private int expireTime; + + protected static final long MILLIS_SECOND = 1000; + + protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND; + + private static final Long MILLIS_MINUTE_TEN = 20 * 60 * 1000L; + + @Autowired + private RedisCache redisCache; + + /** + * 获取用户身份信息 + * + * @return 用户信息 + */ + public LoginUser getLoginUser(HttpServletRequest request) + { + // 获取请求携带的令牌 + String token = getToken(request); + if (StringUtils.isNotEmpty(token)) + { + try + { + Claims claims = parseToken(token); + // 解析对应的权限以及用户信息 + String uuid = (String) claims.get(Constants.LOGIN_USER_KEY); + String userKey = getTokenKey(uuid); + LoginUser user = redisCache.getCacheObject(userKey); + return user; + } + catch (Exception e) + { + log.error("获取用户信息异常'{}'", e.getMessage()); + } + } + return null; + } + + /** + * 设置用户身份信息 + */ + public void setLoginUser(LoginUser loginUser) + { + if (StringUtils.isNotNull(loginUser) && StringUtils.isNotEmpty(loginUser.getToken())) + { + refreshToken(loginUser); + } + } + + /** + * 删除用户身份信息 + */ + public void delLoginUser(String token) + { + if (StringUtils.isNotEmpty(token)) + { + String userKey = getTokenKey(token); + redisCache.deleteObject(userKey); + } + } + + /** + * 创建令牌 + * + * @param loginUser 用户信息 + * @return 令牌 + */ + public String createToken(LoginUser loginUser) + { + String token = IdUtils.fastUUID(); + loginUser.setToken(token); + setUserAgent(loginUser); + refreshToken(loginUser); + + Map claims = new HashMap<>(); + claims.put(Constants.LOGIN_USER_KEY, token); + return createToken(claims); + } + + /** + * 验证令牌有效期,相差不足20分钟,自动刷新缓存 + * + * @param loginUser + * @return 令牌 + */ + public void verifyToken(LoginUser loginUser) + { + long expireTime = loginUser.getExpireTime(); + long currentTime = System.currentTimeMillis(); + if (expireTime - currentTime <= MILLIS_MINUTE_TEN) + { + refreshToken(loginUser); + } + } + + /** + * 刷新令牌有效期 + * + * @param loginUser 登录信息 + */ + public void refreshToken(LoginUser loginUser) + { + loginUser.setLoginTime(System.currentTimeMillis()); + loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE); + // 根据uuid将loginUser缓存 + String userKey = getTokenKey(loginUser.getToken()); + redisCache.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES); + } + + /** + * 设置用户代理信息 + * + * @param loginUser 登录信息 + */ + public void setUserAgent(LoginUser loginUser) + { + UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent")); + String ip = IpUtils.getIpAddr(); + loginUser.setIpaddr(ip); + loginUser.setLoginLocation(AddressUtils.getRealAddressByIP(ip)); + loginUser.setBrowser(userAgent.getBrowser().getName()); + loginUser.setOs(userAgent.getOperatingSystem().getName()); + } + + /** + * 从数据声明生成令牌 + * + * @param claims 数据声明 + * @return 令牌 + */ + public String createToken(Map claims) + { + String token = Jwts.builder() + .setClaims(claims) + .signWith(SignatureAlgorithm.HS512, secret).compact(); + return token; + } + + /** + * 从令牌中获取数据声明 + * + * @param token 令牌 + * @return 数据声明 + */ + public Claims parseToken(String token) + { + return Jwts.parser() + .setSigningKey(secret) + .parseClaimsJws(token) + .getBody(); + } + + /** + * 从令牌中获取用户名 + * + * @param token 令牌 + * @return 用户名 + */ + public String getUsernameFromToken(String token) + { + Claims claims = parseToken(token); + return claims.getSubject(); + } + + /** + * 获取请求token + * + * @param request + * @return token + */ + private String getToken(HttpServletRequest request) + { + String token = request.getHeader(header); + if (StringUtils.isNotEmpty(token) && token.startsWith(Constants.TOKEN_PREFIX)) + { + token = token.replace(Constants.TOKEN_PREFIX, ""); + } + return token; + } + + private String getTokenKey(String uuid) + { + return CacheConstants.LOGIN_TOKEN_KEY + uuid; + } +} diff --git a/zzyl-framework/src/main/java/com/zzyl/framework/web/service/UserDetailsServiceImpl.java b/zzyl-framework/src/main/java/com/zzyl/framework/web/service/UserDetailsServiceImpl.java new file mode 100644 index 0000000..1e9051f --- /dev/null +++ b/zzyl-framework/src/main/java/com/zzyl/framework/web/service/UserDetailsServiceImpl.java @@ -0,0 +1,66 @@ +package com.zzyl.framework.web.service; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; +import com.zzyl.common.core.domain.entity.SysUser; +import com.zzyl.common.core.domain.model.LoginUser; +import com.zzyl.common.enums.UserStatus; +import com.zzyl.common.exception.ServiceException; +import com.zzyl.common.utils.MessageUtils; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.system.service.ISysUserService; + +/** + * 用户验证处理 + * + * @author ruoyi + */ +@Service +public class UserDetailsServiceImpl implements UserDetailsService +{ + private static final Logger log = LoggerFactory.getLogger(UserDetailsServiceImpl.class); + + @Autowired + private ISysUserService userService; + + @Autowired + private SysPasswordService passwordService; + + @Autowired + private SysPermissionService permissionService; + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException + { + SysUser user = userService.selectUserByUserName(username); + if (StringUtils.isNull(user)) + { + log.info("登录用户:{} 不存在.", username); + throw new ServiceException(MessageUtils.message("user.not.exists")); + } + else if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) + { + log.info("登录用户:{} 已被删除.", username); + throw new ServiceException(MessageUtils.message("user.password.delete")); + } + else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) + { + log.info("登录用户:{} 已被停用.", username); + throw new ServiceException(MessageUtils.message("user.blocked")); + } + + passwordService.validate(user); + + return createLoginUser(user); + } + + public UserDetails createLoginUser(SysUser user) + { + return new LoginUser(user.getUserId(), user.getDeptId(), user, permissionService.getMenuPermission(user)); + } +} diff --git a/zzyl-generator/pom.xml b/zzyl-generator/pom.xml new file mode 100644 index 0000000..7685c5c --- /dev/null +++ b/zzyl-generator/pom.xml @@ -0,0 +1,40 @@ + + + + zzyl + com.zzyl + 3.8.8 + + 4.0.0 + + zzyl-generator + + + generator代码生成 + + + + + + + org.apache.velocity + velocity-engine-core + + + + + com.zzyl + zzyl-common + + + + + com.alibaba + druid-spring-boot-starter + + + + + \ No newline at end of file diff --git a/zzyl-generator/src/main/java/com/zzyl/generator/config/GenConfig.java b/zzyl-generator/src/main/java/com/zzyl/generator/config/GenConfig.java new file mode 100644 index 0000000..0a2b4f6 --- /dev/null +++ b/zzyl-generator/src/main/java/com/zzyl/generator/config/GenConfig.java @@ -0,0 +1,87 @@ +package com.zzyl.generator.config; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.PropertySource; +import org.springframework.stereotype.Component; + +/** + * 读取代码生成相关配置 + * + * @author ruoyi + */ +@Component +@ConfigurationProperties(prefix = "gen") +@PropertySource(value = { "classpath:generator.yml" }) +public class GenConfig +{ + /** 作者 */ + public static String author; + + /** 生成包路径 */ + public static String packageName; + + /** 自动去除表前缀 */ + public static boolean autoRemovePre; + + /** 表前缀 */ + public static String tablePrefix; + + /** 是否允许生成文件覆盖到本地(自定义路径) */ + public static boolean allowOverwrite; + + public static String getAuthor() + { + return author; + } + + @Value("${author}") + public void setAuthor(String author) + { + GenConfig.author = author; + } + + public static String getPackageName() + { + return packageName; + } + + @Value("${packageName}") + public void setPackageName(String packageName) + { + GenConfig.packageName = packageName; + } + + public static boolean getAutoRemovePre() + { + return autoRemovePre; + } + + @Value("${autoRemovePre}") + public void setAutoRemovePre(boolean autoRemovePre) + { + GenConfig.autoRemovePre = autoRemovePre; + } + + public static String getTablePrefix() + { + return tablePrefix; + } + + @Value("${tablePrefix}") + public void setTablePrefix(String tablePrefix) + { + GenConfig.tablePrefix = tablePrefix; + } + + public static boolean isAllowOverwrite() + { + return allowOverwrite; + } + + @Value("${allowOverwrite}") + public void setAllowOverwrite(boolean allowOverwrite) + { + GenConfig.allowOverwrite = allowOverwrite; + } +} diff --git a/zzyl-generator/src/main/java/com/zzyl/generator/controller/GenController.java b/zzyl-generator/src/main/java/com/zzyl/generator/controller/GenController.java new file mode 100644 index 0000000..5f2cbc9 --- /dev/null +++ b/zzyl-generator/src/main/java/com/zzyl/generator/controller/GenController.java @@ -0,0 +1,263 @@ +package com.zzyl.generator.controller; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.servlet.http.HttpServletResponse; +import org.apache.commons.io.IOUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.alibaba.druid.DbType; +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateTableStatement; +import com.zzyl.common.annotation.Log; +import com.zzyl.common.core.controller.BaseController; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.core.page.TableDataInfo; +import com.zzyl.common.core.text.Convert; +import com.zzyl.common.enums.BusinessType; +import com.zzyl.common.utils.SecurityUtils; +import com.zzyl.common.utils.sql.SqlUtil; +import com.zzyl.generator.config.GenConfig; +import com.zzyl.generator.domain.GenTable; +import com.zzyl.generator.domain.GenTableColumn; +import com.zzyl.generator.service.IGenTableColumnService; +import com.zzyl.generator.service.IGenTableService; + +/** + * 代码生成 操作处理 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/tool/gen") +public class GenController extends BaseController +{ + @Autowired + private IGenTableService genTableService; + + @Autowired + private IGenTableColumnService genTableColumnService; + + /** + * 查询代码生成列表 + */ + @PreAuthorize("@ss.hasPermi('tool:gen:list')") + @GetMapping("/list") + public TableDataInfo genList(GenTable genTable) + { + startPage(); + List list = genTableService.selectGenTableList(genTable); + return getDataTable(list); + } + + /** + * 修改代码生成业务 + */ + @PreAuthorize("@ss.hasPermi('tool:gen:query')") + @GetMapping(value = "/{tableId}") + public AjaxResult getInfo(@PathVariable Long tableId) + { + GenTable table = genTableService.selectGenTableById(tableId); + List tables = genTableService.selectGenTableAll(); + List list = genTableColumnService.selectGenTableColumnListByTableId(tableId); + Map map = new HashMap(); + map.put("info", table); + map.put("rows", list); + map.put("tables", tables); + return success(map); + } + + /** + * 查询数据库列表 + */ + @PreAuthorize("@ss.hasPermi('tool:gen:list')") + @GetMapping("/db/list") + public TableDataInfo dataList(GenTable genTable) + { + startPage(); + List list = genTableService.selectDbTableList(genTable); + return getDataTable(list); + } + + /** + * 查询数据表字段列表 + */ + @PreAuthorize("@ss.hasPermi('tool:gen:list')") + @GetMapping(value = "/column/{tableId}") + public TableDataInfo columnList(Long tableId) + { + TableDataInfo dataInfo = new TableDataInfo(); + List list = genTableColumnService.selectGenTableColumnListByTableId(tableId); + dataInfo.setRows(list); + dataInfo.setTotal(list.size()); + return dataInfo; + } + + /** + * 导入表结构(保存) + */ + @PreAuthorize("@ss.hasPermi('tool:gen:import')") + @Log(title = "代码生成", businessType = BusinessType.IMPORT) + @PostMapping("/importTable") + public AjaxResult importTableSave(String tables) + { + String[] tableNames = Convert.toStrArray(tables); + // 查询表信息 + List tableList = genTableService.selectDbTableListByNames(tableNames); + genTableService.importGenTable(tableList, SecurityUtils.getUsername()); + return success(); + } + + /** + * 创建表结构(保存) + */ + @PreAuthorize("@ss.hasRole('admin')") + @Log(title = "创建表", businessType = BusinessType.OTHER) + @PostMapping("/createTable") + public AjaxResult createTableSave(String sql) + { + try + { + SqlUtil.filterKeyword(sql); + List sqlStatements = SQLUtils.parseStatements(sql, DbType.mysql); + List tableNames = new ArrayList<>(); + for (SQLStatement sqlStatement : sqlStatements) + { + if (sqlStatement instanceof MySqlCreateTableStatement) + { + MySqlCreateTableStatement createTableStatement = (MySqlCreateTableStatement) sqlStatement; + if (genTableService.createTable(createTableStatement.toString())) + { + String tableName = createTableStatement.getTableName().replaceAll("`", ""); + tableNames.add(tableName); + } + } + } + List tableList = genTableService.selectDbTableListByNames(tableNames.toArray(new String[tableNames.size()])); + String operName = SecurityUtils.getUsername(); + genTableService.importGenTable(tableList, operName); + return AjaxResult.success(); + } + catch (Exception e) + { + logger.error(e.getMessage(), e); + return AjaxResult.error("创建表结构异常"); + } + } + + /** + * 修改保存代码生成业务 + */ + @PreAuthorize("@ss.hasPermi('tool:gen:edit')") + @Log(title = "代码生成", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult editSave(@Validated @RequestBody GenTable genTable) + { + genTableService.validateEdit(genTable); + genTableService.updateGenTable(genTable); + return success(); + } + + /** + * 删除代码生成 + */ + @PreAuthorize("@ss.hasPermi('tool:gen:remove')") + @Log(title = "代码生成", businessType = BusinessType.DELETE) + @DeleteMapping("/{tableIds}") + public AjaxResult remove(@PathVariable Long[] tableIds) + { + genTableService.deleteGenTableByIds(tableIds); + return success(); + } + + /** + * 预览代码 + */ + @PreAuthorize("@ss.hasPermi('tool:gen:preview')") + @GetMapping("/preview/{tableId}") + public AjaxResult preview(@PathVariable("tableId") Long tableId) throws IOException + { + Map dataMap = genTableService.previewCode(tableId); + return success(dataMap); + } + + /** + * 生成代码(下载方式) + */ + @PreAuthorize("@ss.hasPermi('tool:gen:code')") + @Log(title = "代码生成", businessType = BusinessType.GENCODE) + @GetMapping("/download/{tableName}") + public void download(HttpServletResponse response, @PathVariable("tableName") String tableName) throws IOException + { + byte[] data = genTableService.downloadCode(tableName); + genCode(response, data); + } + + /** + * 生成代码(自定义路径) + */ + @PreAuthorize("@ss.hasPermi('tool:gen:code')") + @Log(title = "代码生成", businessType = BusinessType.GENCODE) + @GetMapping("/genCode/{tableName}") + public AjaxResult genCode(@PathVariable("tableName") String tableName) + { + if (!GenConfig.isAllowOverwrite()) + { + return AjaxResult.error("【系统预设】不允许生成文件覆盖到本地"); + } + genTableService.generatorCode(tableName); + return success(); + } + + /** + * 同步数据库 + */ + @PreAuthorize("@ss.hasPermi('tool:gen:edit')") + @Log(title = "代码生成", businessType = BusinessType.UPDATE) + @GetMapping("/synchDb/{tableName}") + public AjaxResult synchDb(@PathVariable("tableName") String tableName) + { + genTableService.synchDb(tableName); + return success(); + } + + /** + * 批量生成代码 + */ + @PreAuthorize("@ss.hasPermi('tool:gen:code')") + @Log(title = "代码生成", businessType = BusinessType.GENCODE) + @GetMapping("/batchGenCode") + public void batchGenCode(HttpServletResponse response, String tables) throws IOException + { + String[] tableNames = Convert.toStrArray(tables); + byte[] data = genTableService.downloadCode(tableNames); + genCode(response, data); + } + + /** + * 生成zip文件 + */ + private void genCode(HttpServletResponse response, byte[] data) throws IOException + { + response.reset(); + response.addHeader("Access-Control-Allow-Origin", "*"); + response.addHeader("Access-Control-Expose-Headers", "Content-Disposition"); + response.setHeader("Content-Disposition", "attachment; filename=\"ruoyi.zip\""); + response.addHeader("Content-Length", "" + data.length); + response.setContentType("application/octet-stream; charset=UTF-8"); + IOUtils.write(data, response.getOutputStream()); + } +} \ No newline at end of file diff --git a/zzyl-generator/src/main/java/com/zzyl/generator/domain/GenTable.java b/zzyl-generator/src/main/java/com/zzyl/generator/domain/GenTable.java new file mode 100644 index 0000000..6dbe161 --- /dev/null +++ b/zzyl-generator/src/main/java/com/zzyl/generator/domain/GenTable.java @@ -0,0 +1,385 @@ +package com.zzyl.generator.domain; + +import java.util.List; +import javax.validation.Valid; +import javax.validation.constraints.NotBlank; +import org.apache.commons.lang3.ArrayUtils; +import com.zzyl.common.constant.GenConstants; +import com.zzyl.common.core.domain.BaseEntity; +import com.zzyl.common.utils.StringUtils; + +/** + * 业务表 gen_table + * + * @author ruoyi + */ +public class GenTable extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 编号 */ + private Long tableId; + + /** 表名称 */ + @NotBlank(message = "表名称不能为空") + private String tableName; + + /** 表描述 */ + @NotBlank(message = "表描述不能为空") + private String tableComment; + + /** 关联父表的表名 */ + private String subTableName; + + /** 本表关联父表的外键名 */ + private String subTableFkName; + + /** 实体类名称(首字母大写) */ + @NotBlank(message = "实体类名称不能为空") + private String className; + + /** 使用的模板(crud单表操作 tree树表操作 sub主子表操作) */ + private String tplCategory; + + /** 前端类型(element-ui模版 element-plus模版) */ + private String tplWebType; + + /** 生成包路径 */ + @NotBlank(message = "生成包路径不能为空") + private String packageName; + + /** 生成模块名 */ + @NotBlank(message = "生成模块名不能为空") + private String moduleName; + + /** 生成业务名 */ + @NotBlank(message = "生成业务名不能为空") + private String businessName; + + /** 生成功能名 */ + @NotBlank(message = "生成功能名不能为空") + private String functionName; + + /** 生成作者 */ + @NotBlank(message = "作者不能为空") + private String functionAuthor; + + /** 生成代码方式(0zip压缩包 1自定义路径) */ + private String genType; + + /** 生成路径(不填默认项目路径) */ + private String genPath; + + /** 主键信息 */ + private GenTableColumn pkColumn; + + /** 子表信息 */ + private GenTable subTable; + + /** 表列信息 */ + @Valid + private List columns; + + /** 其它生成选项 */ + private String options; + + /** 树编码字段 */ + private String treeCode; + + /** 树父编码字段 */ + private String treeParentCode; + + /** 树名称字段 */ + private String treeName; + + /** 上级菜单ID字段 */ + private Long parentMenuId; + + /** 上级菜单名称字段 */ + private String parentMenuName; + + public Long getTableId() + { + return tableId; + } + + public void setTableId(Long tableId) + { + this.tableId = tableId; + } + + public String getTableName() + { + return tableName; + } + + public void setTableName(String tableName) + { + this.tableName = tableName; + } + + public String getTableComment() + { + return tableComment; + } + + public void setTableComment(String tableComment) + { + this.tableComment = tableComment; + } + + public String getSubTableName() + { + return subTableName; + } + + public void setSubTableName(String subTableName) + { + this.subTableName = subTableName; + } + + public String getSubTableFkName() + { + return subTableFkName; + } + + public void setSubTableFkName(String subTableFkName) + { + this.subTableFkName = subTableFkName; + } + + public String getClassName() + { + return className; + } + + public void setClassName(String className) + { + this.className = className; + } + + public String getTplCategory() + { + return tplCategory; + } + + public void setTplCategory(String tplCategory) + { + this.tplCategory = tplCategory; + } + + public String getTplWebType() + { + return tplWebType; + } + + public void setTplWebType(String tplWebType) + { + this.tplWebType = tplWebType; + } + + public String getPackageName() + { + return packageName; + } + + public void setPackageName(String packageName) + { + this.packageName = packageName; + } + + public String getModuleName() + { + return moduleName; + } + + public void setModuleName(String moduleName) + { + this.moduleName = moduleName; + } + + public String getBusinessName() + { + return businessName; + } + + public void setBusinessName(String businessName) + { + this.businessName = businessName; + } + + public String getFunctionName() + { + return functionName; + } + + public void setFunctionName(String functionName) + { + this.functionName = functionName; + } + + public String getFunctionAuthor() + { + return functionAuthor; + } + + public void setFunctionAuthor(String functionAuthor) + { + this.functionAuthor = functionAuthor; + } + + public String getGenType() + { + return genType; + } + + public void setGenType(String genType) + { + this.genType = genType; + } + + public String getGenPath() + { + return genPath; + } + + public void setGenPath(String genPath) + { + this.genPath = genPath; + } + + public GenTableColumn getPkColumn() + { + return pkColumn; + } + + public void setPkColumn(GenTableColumn pkColumn) + { + this.pkColumn = pkColumn; + } + + public GenTable getSubTable() + { + return subTable; + } + + public void setSubTable(GenTable subTable) + { + this.subTable = subTable; + } + + public List getColumns() + { + return columns; + } + + public void setColumns(List columns) + { + this.columns = columns; + } + + public String getOptions() + { + return options; + } + + public void setOptions(String options) + { + this.options = options; + } + + public String getTreeCode() + { + return treeCode; + } + + public void setTreeCode(String treeCode) + { + this.treeCode = treeCode; + } + + public String getTreeParentCode() + { + return treeParentCode; + } + + public void setTreeParentCode(String treeParentCode) + { + this.treeParentCode = treeParentCode; + } + + public String getTreeName() + { + return treeName; + } + + public void setTreeName(String treeName) + { + this.treeName = treeName; + } + + public Long getParentMenuId() + { + return parentMenuId; + } + + public void setParentMenuId(Long parentMenuId) + { + this.parentMenuId = parentMenuId; + } + + public String getParentMenuName() + { + return parentMenuName; + } + + public void setParentMenuName(String parentMenuName) + { + this.parentMenuName = parentMenuName; + } + + public boolean isSub() + { + return isSub(this.tplCategory); + } + + public static boolean isSub(String tplCategory) + { + return tplCategory != null && StringUtils.equals(GenConstants.TPL_SUB, tplCategory); + } + + public boolean isTree() + { + return isTree(this.tplCategory); + } + + public static boolean isTree(String tplCategory) + { + return tplCategory != null && StringUtils.equals(GenConstants.TPL_TREE, tplCategory); + } + + public boolean isCrud() + { + return isCrud(this.tplCategory); + } + + public static boolean isCrud(String tplCategory) + { + return tplCategory != null && StringUtils.equals(GenConstants.TPL_CRUD, tplCategory); + } + + public boolean isSuperColumn(String javaField) + { + return isSuperColumn(this.tplCategory, javaField); + } + + public static boolean isSuperColumn(String tplCategory, String javaField) + { + if (isTree(tplCategory)) + { + return StringUtils.equalsAnyIgnoreCase(javaField, + ArrayUtils.addAll(GenConstants.TREE_ENTITY, GenConstants.BASE_ENTITY)); + } + return StringUtils.equalsAnyIgnoreCase(javaField, GenConstants.BASE_ENTITY); + } +} \ No newline at end of file diff --git a/zzyl-generator/src/main/java/com/zzyl/generator/domain/GenTableColumn.java b/zzyl-generator/src/main/java/com/zzyl/generator/domain/GenTableColumn.java new file mode 100644 index 0000000..395fd50 --- /dev/null +++ b/zzyl-generator/src/main/java/com/zzyl/generator/domain/GenTableColumn.java @@ -0,0 +1,373 @@ +package com.zzyl.generator.domain; + +import javax.validation.constraints.NotBlank; +import com.zzyl.common.core.domain.BaseEntity; +import com.zzyl.common.utils.StringUtils; + +/** + * 代码生成业务字段表 gen_table_column + * + * @author ruoyi + */ +public class GenTableColumn extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 编号 */ + private Long columnId; + + /** 归属表编号 */ + private Long tableId; + + /** 列名称 */ + private String columnName; + + /** 列描述 */ + private String columnComment; + + /** 列类型 */ + private String columnType; + + /** JAVA类型 */ + private String javaType; + + /** JAVA字段名 */ + @NotBlank(message = "Java属性不能为空") + private String javaField; + + /** 是否主键(1是) */ + private String isPk; + + /** 是否自增(1是) */ + private String isIncrement; + + /** 是否必填(1是) */ + private String isRequired; + + /** 是否为插入字段(1是) */ + private String isInsert; + + /** 是否编辑字段(1是) */ + private String isEdit; + + /** 是否列表字段(1是) */ + private String isList; + + /** 是否查询字段(1是) */ + private String isQuery; + + /** 查询方式(EQ等于、NE不等于、GT大于、LT小于、LIKE模糊、BETWEEN范围) */ + private String queryType; + + /** 显示类型(input文本框、textarea文本域、select下拉框、checkbox复选框、radio单选框、datetime日期控件、image图片上传控件、upload文件上传控件、editor富文本控件) */ + private String htmlType; + + /** 字典类型 */ + private String dictType; + + /** 排序 */ + private Integer sort; + + public void setColumnId(Long columnId) + { + this.columnId = columnId; + } + + public Long getColumnId() + { + return columnId; + } + + public void setTableId(Long tableId) + { + this.tableId = tableId; + } + + public Long getTableId() + { + return tableId; + } + + public void setColumnName(String columnName) + { + this.columnName = columnName; + } + + public String getColumnName() + { + return columnName; + } + + public void setColumnComment(String columnComment) + { + this.columnComment = columnComment; + } + + public String getColumnComment() + { + return columnComment; + } + + public void setColumnType(String columnType) + { + this.columnType = columnType; + } + + public String getColumnType() + { + return columnType; + } + + public void setJavaType(String javaType) + { + this.javaType = javaType; + } + + public String getJavaType() + { + return javaType; + } + + public void setJavaField(String javaField) + { + this.javaField = javaField; + } + + public String getJavaField() + { + return javaField; + } + + public String getCapJavaField() + { + return StringUtils.capitalize(javaField); + } + + public void setIsPk(String isPk) + { + this.isPk = isPk; + } + + public String getIsPk() + { + return isPk; + } + + public boolean isPk() + { + return isPk(this.isPk); + } + + public boolean isPk(String isPk) + { + return isPk != null && StringUtils.equals("1", isPk); + } + + public String getIsIncrement() + { + return isIncrement; + } + + public void setIsIncrement(String isIncrement) + { + this.isIncrement = isIncrement; + } + + public boolean isIncrement() + { + return isIncrement(this.isIncrement); + } + + public boolean isIncrement(String isIncrement) + { + return isIncrement != null && StringUtils.equals("1", isIncrement); + } + + public void setIsRequired(String isRequired) + { + this.isRequired = isRequired; + } + + public String getIsRequired() + { + return isRequired; + } + + public boolean isRequired() + { + return isRequired(this.isRequired); + } + + public boolean isRequired(String isRequired) + { + return isRequired != null && StringUtils.equals("1", isRequired); + } + + public void setIsInsert(String isInsert) + { + this.isInsert = isInsert; + } + + public String getIsInsert() + { + return isInsert; + } + + public boolean isInsert() + { + return isInsert(this.isInsert); + } + + public boolean isInsert(String isInsert) + { + return isInsert != null && StringUtils.equals("1", isInsert); + } + + public void setIsEdit(String isEdit) + { + this.isEdit = isEdit; + } + + public String getIsEdit() + { + return isEdit; + } + + public boolean isEdit() + { + return isInsert(this.isEdit); + } + + public boolean isEdit(String isEdit) + { + return isEdit != null && StringUtils.equals("1", isEdit); + } + + public void setIsList(String isList) + { + this.isList = isList; + } + + public String getIsList() + { + return isList; + } + + public boolean isList() + { + return isList(this.isList); + } + + public boolean isList(String isList) + { + return isList != null && StringUtils.equals("1", isList); + } + + public void setIsQuery(String isQuery) + { + this.isQuery = isQuery; + } + + public String getIsQuery() + { + return isQuery; + } + + public boolean isQuery() + { + return isQuery(this.isQuery); + } + + public boolean isQuery(String isQuery) + { + return isQuery != null && StringUtils.equals("1", isQuery); + } + + public void setQueryType(String queryType) + { + this.queryType = queryType; + } + + public String getQueryType() + { + return queryType; + } + + public String getHtmlType() + { + return htmlType; + } + + public void setHtmlType(String htmlType) + { + this.htmlType = htmlType; + } + + public void setDictType(String dictType) + { + this.dictType = dictType; + } + + public String getDictType() + { + return dictType; + } + + public void setSort(Integer sort) + { + this.sort = sort; + } + + public Integer getSort() + { + return sort; + } + + public boolean isSuperColumn() + { + return isSuperColumn(this.javaField); + } + + public static boolean isSuperColumn(String javaField) + { + return StringUtils.equalsAnyIgnoreCase(javaField, + // BaseEntity + "createBy", "createTime", "updateBy", "updateTime", "remark", + // TreeEntity + "parentName", "parentId", "orderNum", "ancestors"); + } + + public boolean isUsableColumn() + { + return isUsableColumn(javaField); + } + + public static boolean isUsableColumn(String javaField) + { + // isSuperColumn()中的名单用于避免生成多余Domain属性,若某些属性在生成页面时需要用到不能忽略,则放在此处白名单 + return StringUtils.equalsAnyIgnoreCase(javaField, "parentId", "orderNum", "remark"); + } + + public String readConverterExp() + { + String remarks = StringUtils.substringBetween(this.columnComment, "(", ")"); + StringBuffer sb = new StringBuffer(); + if (StringUtils.isNotEmpty(remarks)) + { + for (String value : remarks.split(" ")) + { + if (StringUtils.isNotEmpty(value)) + { + Object startStr = value.subSequence(0, 1); + String endStr = value.substring(1); + sb.append("").append(startStr).append("=").append(endStr).append(","); + } + } + return sb.deleteCharAt(sb.length() - 1).toString(); + } + else + { + return this.columnComment; + } + } +} diff --git a/zzyl-generator/src/main/java/com/zzyl/generator/mapper/GenTableColumnMapper.java b/zzyl-generator/src/main/java/com/zzyl/generator/mapper/GenTableColumnMapper.java new file mode 100644 index 0000000..3e63232 --- /dev/null +++ b/zzyl-generator/src/main/java/com/zzyl/generator/mapper/GenTableColumnMapper.java @@ -0,0 +1,60 @@ +package com.zzyl.generator.mapper; + +import java.util.List; +import com.zzyl.generator.domain.GenTableColumn; + +/** + * 业务字段 数据层 + * + * @author ruoyi + */ +public interface GenTableColumnMapper +{ + /** + * 根据表名称查询列信息 + * + * @param tableName 表名称 + * @return 列信息 + */ + public List selectDbTableColumnsByName(String tableName); + + /** + * 查询业务字段列表 + * + * @param tableId 业务字段编号 + * @return 业务字段集合 + */ + public List selectGenTableColumnListByTableId(Long tableId); + + /** + * 新增业务字段 + * + * @param genTableColumn 业务字段信息 + * @return 结果 + */ + public int insertGenTableColumn(GenTableColumn genTableColumn); + + /** + * 修改业务字段 + * + * @param genTableColumn 业务字段信息 + * @return 结果 + */ + public int updateGenTableColumn(GenTableColumn genTableColumn); + + /** + * 删除业务字段 + * + * @param genTableColumns 列数据 + * @return 结果 + */ + public int deleteGenTableColumns(List genTableColumns); + + /** + * 批量删除业务字段 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteGenTableColumnByIds(Long[] ids); +} diff --git a/zzyl-generator/src/main/java/com/zzyl/generator/mapper/GenTableMapper.java b/zzyl-generator/src/main/java/com/zzyl/generator/mapper/GenTableMapper.java new file mode 100644 index 0000000..66fcc87 --- /dev/null +++ b/zzyl-generator/src/main/java/com/zzyl/generator/mapper/GenTableMapper.java @@ -0,0 +1,91 @@ +package com.zzyl.generator.mapper; + +import java.util.List; +import com.zzyl.generator.domain.GenTable; + +/** + * 业务 数据层 + * + * @author ruoyi + */ +public interface GenTableMapper +{ + /** + * 查询业务列表 + * + * @param genTable 业务信息 + * @return 业务集合 + */ + public List selectGenTableList(GenTable genTable); + + /** + * 查询据库列表 + * + * @param genTable 业务信息 + * @return 数据库表集合 + */ + public List selectDbTableList(GenTable genTable); + + /** + * 查询据库列表 + * + * @param tableNames 表名称组 + * @return 数据库表集合 + */ + public List selectDbTableListByNames(String[] tableNames); + + /** + * 查询所有表信息 + * + * @return 表信息集合 + */ + public List selectGenTableAll(); + + /** + * 查询表ID业务信息 + * + * @param id 业务ID + * @return 业务信息 + */ + public GenTable selectGenTableById(Long id); + + /** + * 查询表名称业务信息 + * + * @param tableName 表名称 + * @return 业务信息 + */ + public GenTable selectGenTableByName(String tableName); + + /** + * 新增业务 + * + * @param genTable 业务信息 + * @return 结果 + */ + public int insertGenTable(GenTable genTable); + + /** + * 修改业务 + * + * @param genTable 业务信息 + * @return 结果 + */ + public int updateGenTable(GenTable genTable); + + /** + * 批量删除业务 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteGenTableByIds(Long[] ids); + + /** + * 创建表 + * + * @param sql 表结构 + * @return 结果 + */ + public int createTable(String sql); +} diff --git a/zzyl-generator/src/main/java/com/zzyl/generator/service/GenTableColumnServiceImpl.java b/zzyl-generator/src/main/java/com/zzyl/generator/service/GenTableColumnServiceImpl.java new file mode 100644 index 0000000..6b845ad --- /dev/null +++ b/zzyl-generator/src/main/java/com/zzyl/generator/service/GenTableColumnServiceImpl.java @@ -0,0 +1,68 @@ +package com.zzyl.generator.service; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.zzyl.common.core.text.Convert; +import com.zzyl.generator.domain.GenTableColumn; +import com.zzyl.generator.mapper.GenTableColumnMapper; + +/** + * 业务字段 服务层实现 + * + * @author ruoyi + */ +@Service +public class GenTableColumnServiceImpl implements IGenTableColumnService +{ + @Autowired + private GenTableColumnMapper genTableColumnMapper; + + /** + * 查询业务字段列表 + * + * @param tableId 业务字段编号 + * @return 业务字段集合 + */ + @Override + public List selectGenTableColumnListByTableId(Long tableId) + { + return genTableColumnMapper.selectGenTableColumnListByTableId(tableId); + } + + /** + * 新增业务字段 + * + * @param genTableColumn 业务字段信息 + * @return 结果 + */ + @Override + public int insertGenTableColumn(GenTableColumn genTableColumn) + { + return genTableColumnMapper.insertGenTableColumn(genTableColumn); + } + + /** + * 修改业务字段 + * + * @param genTableColumn 业务字段信息 + * @return 结果 + */ + @Override + public int updateGenTableColumn(GenTableColumn genTableColumn) + { + return genTableColumnMapper.updateGenTableColumn(genTableColumn); + } + + /** + * 删除业务字段对象 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + @Override + public int deleteGenTableColumnByIds(String ids) + { + return genTableColumnMapper.deleteGenTableColumnByIds(Convert.toLongArray(ids)); + } +} diff --git a/zzyl-generator/src/main/java/com/zzyl/generator/service/GenTableServiceImpl.java b/zzyl-generator/src/main/java/com/zzyl/generator/service/GenTableServiceImpl.java new file mode 100644 index 0000000..cb55080 --- /dev/null +++ b/zzyl-generator/src/main/java/com/zzyl/generator/service/GenTableServiceImpl.java @@ -0,0 +1,531 @@ +package com.zzyl.generator.service; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.StringWriter; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.apache.velocity.Template; +import org.apache.velocity.VelocityContext; +import org.apache.velocity.app.Velocity; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.zzyl.common.constant.Constants; +import com.zzyl.common.constant.GenConstants; +import com.zzyl.common.core.text.CharsetKit; +import com.zzyl.common.exception.ServiceException; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.generator.domain.GenTable; +import com.zzyl.generator.domain.GenTableColumn; +import com.zzyl.generator.mapper.GenTableColumnMapper; +import com.zzyl.generator.mapper.GenTableMapper; +import com.zzyl.generator.util.GenUtils; +import com.zzyl.generator.util.VelocityInitializer; +import com.zzyl.generator.util.VelocityUtils; + +/** + * 业务 服务层实现 + * + * @author ruoyi + */ +@Service +public class GenTableServiceImpl implements IGenTableService +{ + private static final Logger log = LoggerFactory.getLogger(GenTableServiceImpl.class); + + @Autowired + private GenTableMapper genTableMapper; + + @Autowired + private GenTableColumnMapper genTableColumnMapper; + + /** + * 查询业务信息 + * + * @param id 业务ID + * @return 业务信息 + */ + @Override + public GenTable selectGenTableById(Long id) + { + GenTable genTable = genTableMapper.selectGenTableById(id); + setTableFromOptions(genTable); + return genTable; + } + + /** + * 查询业务列表 + * + * @param genTable 业务信息 + * @return 业务集合 + */ + @Override + public List selectGenTableList(GenTable genTable) + { + return genTableMapper.selectGenTableList(genTable); + } + + /** + * 查询据库列表 + * + * @param genTable 业务信息 + * @return 数据库表集合 + */ + @Override + public List selectDbTableList(GenTable genTable) + { + return genTableMapper.selectDbTableList(genTable); + } + + /** + * 查询据库列表 + * + * @param tableNames 表名称组 + * @return 数据库表集合 + */ + @Override + public List selectDbTableListByNames(String[] tableNames) + { + return genTableMapper.selectDbTableListByNames(tableNames); + } + + /** + * 查询所有表信息 + * + * @return 表信息集合 + */ + @Override + public List selectGenTableAll() + { + return genTableMapper.selectGenTableAll(); + } + + /** + * 修改业务 + * + * @param genTable 业务信息 + * @return 结果 + */ + @Override + @Transactional + public void updateGenTable(GenTable genTable) + { + String options = JSON.toJSONString(genTable.getParams()); + genTable.setOptions(options); + int row = genTableMapper.updateGenTable(genTable); + if (row > 0) + { + for (GenTableColumn cenTableColumn : genTable.getColumns()) + { + genTableColumnMapper.updateGenTableColumn(cenTableColumn); + } + } + } + + /** + * 删除业务对象 + * + * @param tableIds 需要删除的数据ID + * @return 结果 + */ + @Override + @Transactional + public void deleteGenTableByIds(Long[] tableIds) + { + genTableMapper.deleteGenTableByIds(tableIds); + genTableColumnMapper.deleteGenTableColumnByIds(tableIds); + } + + /** + * 创建表 + * + * @param sql 创建表语句 + * @return 结果 + */ + @Override + public boolean createTable(String sql) + { + return genTableMapper.createTable(sql) == 0; + } + + /** + * 导入表结构 + * + * @param tableList 导入表列表 + */ + @Override + @Transactional + public void importGenTable(List tableList, String operName) + { + try + { + for (GenTable table : tableList) + { + String tableName = table.getTableName(); + GenUtils.initTable(table, operName); + int row = genTableMapper.insertGenTable(table); + if (row > 0) + { + // 保存列信息 + List genTableColumns = genTableColumnMapper.selectDbTableColumnsByName(tableName); + for (GenTableColumn column : genTableColumns) + { + GenUtils.initColumnField(column, table); + genTableColumnMapper.insertGenTableColumn(column); + } + } + } + } + catch (Exception e) + { + throw new ServiceException("导入失败:" + e.getMessage()); + } + } + + /** + * 预览代码 + * + * @param tableId 表编号 + * @return 预览数据列表 + */ + @Override + public Map previewCode(Long tableId) + { + Map dataMap = new LinkedHashMap<>(); + // 查询表信息 + GenTable table = genTableMapper.selectGenTableById(tableId); + // 设置主子表信息 + setSubTable(table); + // 设置主键列信息 + setPkColumn(table); + VelocityInitializer.initVelocity(); + + VelocityContext context = VelocityUtils.prepareContext(table); + + // 获取模板列表 + List templates = VelocityUtils.getTemplateList(table.getTplCategory(), table.getTplWebType()); + for (String template : templates) + { + // 渲染模板 + StringWriter sw = new StringWriter(); + Template tpl = Velocity.getTemplate(template, Constants.UTF8); + tpl.merge(context, sw); + dataMap.put(template, sw.toString()); + } + return dataMap; + } + + /** + * 生成代码(下载方式) + * + * @param tableName 表名称 + * @return 数据 + */ + @Override + public byte[] downloadCode(String tableName) + { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + ZipOutputStream zip = new ZipOutputStream(outputStream); + generatorCode(tableName, zip); + IOUtils.closeQuietly(zip); + return outputStream.toByteArray(); + } + + /** + * 生成代码(自定义路径) + * + * @param tableName 表名称 + */ + @Override + public void generatorCode(String tableName) + { + // 查询表信息 + GenTable table = genTableMapper.selectGenTableByName(tableName); + // 设置主子表信息 + setSubTable(table); + // 设置主键列信息 + setPkColumn(table); + + VelocityInitializer.initVelocity(); + + VelocityContext context = VelocityUtils.prepareContext(table); + + // 获取模板列表 + List templates = VelocityUtils.getTemplateList(table.getTplCategory(), table.getTplWebType()); + for (String template : templates) + { + if (!StringUtils.containsAny(template, "sql.vm", "api.js.vm", "index.vue.vm", "index-tree.vue.vm")) + { + // 渲染模板 + StringWriter sw = new StringWriter(); + Template tpl = Velocity.getTemplate(template, Constants.UTF8); + tpl.merge(context, sw); + try + { + String path = getGenPath(table, template); + FileUtils.writeStringToFile(new File(path), sw.toString(), CharsetKit.UTF_8); + } + catch (IOException e) + { + throw new ServiceException("渲染模板失败,表名:" + table.getTableName()); + } + } + } + } + + /** + * 同步数据库 + * + * @param tableName 表名称 + */ + @Override + @Transactional + public void synchDb(String tableName) + { + GenTable table = genTableMapper.selectGenTableByName(tableName); + List tableColumns = table.getColumns(); + Map tableColumnMap = tableColumns.stream().collect(Collectors.toMap(GenTableColumn::getColumnName, Function.identity())); + + List dbTableColumns = genTableColumnMapper.selectDbTableColumnsByName(tableName); + if (StringUtils.isEmpty(dbTableColumns)) + { + throw new ServiceException("同步数据失败,原表结构不存在"); + } + List dbTableColumnNames = dbTableColumns.stream().map(GenTableColumn::getColumnName).collect(Collectors.toList()); + + dbTableColumns.forEach(column -> { + GenUtils.initColumnField(column, table); + if (tableColumnMap.containsKey(column.getColumnName())) + { + GenTableColumn prevColumn = tableColumnMap.get(column.getColumnName()); + column.setColumnId(prevColumn.getColumnId()); + if (column.isList()) + { + // 如果是列表,继续保留查询方式/字典类型选项 + column.setDictType(prevColumn.getDictType()); + column.setQueryType(prevColumn.getQueryType()); + } + if (StringUtils.isNotEmpty(prevColumn.getIsRequired()) && !column.isPk() + && (column.isInsert() || column.isEdit()) + && ((column.isUsableColumn()) || (!column.isSuperColumn()))) + { + // 如果是(新增/修改&非主键/非忽略及父属性),继续保留必填/显示类型选项 + column.setIsRequired(prevColumn.getIsRequired()); + column.setHtmlType(prevColumn.getHtmlType()); + } + genTableColumnMapper.updateGenTableColumn(column); + } + else + { + genTableColumnMapper.insertGenTableColumn(column); + } + }); + + List delColumns = tableColumns.stream().filter(column -> !dbTableColumnNames.contains(column.getColumnName())).collect(Collectors.toList()); + if (StringUtils.isNotEmpty(delColumns)) + { + genTableColumnMapper.deleteGenTableColumns(delColumns); + } + } + + /** + * 批量生成代码(下载方式) + * + * @param tableNames 表数组 + * @return 数据 + */ + @Override + public byte[] downloadCode(String[] tableNames) + { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + ZipOutputStream zip = new ZipOutputStream(outputStream); + for (String tableName : tableNames) + { + generatorCode(tableName, zip); + } + IOUtils.closeQuietly(zip); + return outputStream.toByteArray(); + } + + /** + * 查询表信息并生成代码 + */ + private void generatorCode(String tableName, ZipOutputStream zip) + { + // 查询表信息 + GenTable table = genTableMapper.selectGenTableByName(tableName); + // 设置主子表信息 + setSubTable(table); + // 设置主键列信息 + setPkColumn(table); + + VelocityInitializer.initVelocity(); + + VelocityContext context = VelocityUtils.prepareContext(table); + + // 获取模板列表 + List templates = VelocityUtils.getTemplateList(table.getTplCategory(), table.getTplWebType()); + for (String template : templates) + { + // 渲染模板 + StringWriter sw = new StringWriter(); + Template tpl = Velocity.getTemplate(template, Constants.UTF8); + tpl.merge(context, sw); + try + { + // 添加到zip + zip.putNextEntry(new ZipEntry(VelocityUtils.getFileName(template, table))); + IOUtils.write(sw.toString(), zip, Constants.UTF8); + IOUtils.closeQuietly(sw); + zip.flush(); + zip.closeEntry(); + } + catch (IOException e) + { + log.error("渲染模板失败,表名:" + table.getTableName(), e); + } + } + } + + /** + * 修改保存参数校验 + * + * @param genTable 业务信息 + */ + @Override + public void validateEdit(GenTable genTable) + { + if (GenConstants.TPL_TREE.equals(genTable.getTplCategory())) + { + String options = JSON.toJSONString(genTable.getParams()); + JSONObject paramsObj = JSON.parseObject(options); + if (StringUtils.isEmpty(paramsObj.getString(GenConstants.TREE_CODE))) + { + throw new ServiceException("树编码字段不能为空"); + } + else if (StringUtils.isEmpty(paramsObj.getString(GenConstants.TREE_PARENT_CODE))) + { + throw new ServiceException("树父编码字段不能为空"); + } + else if (StringUtils.isEmpty(paramsObj.getString(GenConstants.TREE_NAME))) + { + throw new ServiceException("树名称字段不能为空"); + } + else if (GenConstants.TPL_SUB.equals(genTable.getTplCategory())) + { + if (StringUtils.isEmpty(genTable.getSubTableName())) + { + throw new ServiceException("关联子表的表名不能为空"); + } + else if (StringUtils.isEmpty(genTable.getSubTableFkName())) + { + throw new ServiceException("子表关联的外键名不能为空"); + } + } + } + } + + /** + * 设置主键列信息 + * + * @param table 业务表信息 + */ + public void setPkColumn(GenTable table) + { + for (GenTableColumn column : table.getColumns()) + { + if (column.isPk()) + { + table.setPkColumn(column); + break; + } + } + if (StringUtils.isNull(table.getPkColumn())) + { + table.setPkColumn(table.getColumns().get(0)); + } + if (GenConstants.TPL_SUB.equals(table.getTplCategory())) + { + for (GenTableColumn column : table.getSubTable().getColumns()) + { + if (column.isPk()) + { + table.getSubTable().setPkColumn(column); + break; + } + } + if (StringUtils.isNull(table.getSubTable().getPkColumn())) + { + table.getSubTable().setPkColumn(table.getSubTable().getColumns().get(0)); + } + } + } + + /** + * 设置主子表信息 + * + * @param table 业务表信息 + */ + public void setSubTable(GenTable table) + { + String subTableName = table.getSubTableName(); + if (StringUtils.isNotEmpty(subTableName)) + { + table.setSubTable(genTableMapper.selectGenTableByName(subTableName)); + } + } + + /** + * 设置代码生成其他选项值 + * + * @param genTable 设置后的生成对象 + */ + public void setTableFromOptions(GenTable genTable) + { + JSONObject paramsObj = JSON.parseObject(genTable.getOptions()); + if (StringUtils.isNotNull(paramsObj)) + { + String treeCode = paramsObj.getString(GenConstants.TREE_CODE); + String treeParentCode = paramsObj.getString(GenConstants.TREE_PARENT_CODE); + String treeName = paramsObj.getString(GenConstants.TREE_NAME); + Long parentMenuId = paramsObj.getLongValue(GenConstants.PARENT_MENU_ID); + String parentMenuName = paramsObj.getString(GenConstants.PARENT_MENU_NAME); + + genTable.setTreeCode(treeCode); + genTable.setTreeParentCode(treeParentCode); + genTable.setTreeName(treeName); + genTable.setParentMenuId(parentMenuId); + genTable.setParentMenuName(parentMenuName); + } + } + + /** + * 获取代码生成地址 + * + * @param table 业务表信息 + * @param template 模板文件路径 + * @return 生成地址 + */ + public static String getGenPath(GenTable table, String template) + { + String genPath = table.getGenPath(); + if (StringUtils.equals(genPath, "/")) + { + return System.getProperty("user.dir") + File.separator + "src" + File.separator + VelocityUtils.getFileName(template, table); + } + return genPath + File.separator + VelocityUtils.getFileName(template, table); + } +} \ No newline at end of file diff --git a/zzyl-generator/src/main/java/com/zzyl/generator/service/IGenTableColumnService.java b/zzyl-generator/src/main/java/com/zzyl/generator/service/IGenTableColumnService.java new file mode 100644 index 0000000..b412664 --- /dev/null +++ b/zzyl-generator/src/main/java/com/zzyl/generator/service/IGenTableColumnService.java @@ -0,0 +1,44 @@ +package com.zzyl.generator.service; + +import java.util.List; +import com.zzyl.generator.domain.GenTableColumn; + +/** + * 业务字段 服务层 + * + * @author ruoyi + */ +public interface IGenTableColumnService +{ + /** + * 查询业务字段列表 + * + * @param tableId 业务字段编号 + * @return 业务字段集合 + */ + public List selectGenTableColumnListByTableId(Long tableId); + + /** + * 新增业务字段 + * + * @param genTableColumn 业务字段信息 + * @return 结果 + */ + public int insertGenTableColumn(GenTableColumn genTableColumn); + + /** + * 修改业务字段 + * + * @param genTableColumn 业务字段信息 + * @return 结果 + */ + public int updateGenTableColumn(GenTableColumn genTableColumn); + + /** + * 删除业务字段信息 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteGenTableColumnByIds(String ids); +} diff --git a/zzyl-generator/src/main/java/com/zzyl/generator/service/IGenTableService.java b/zzyl-generator/src/main/java/com/zzyl/generator/service/IGenTableService.java new file mode 100644 index 0000000..810a15e --- /dev/null +++ b/zzyl-generator/src/main/java/com/zzyl/generator/service/IGenTableService.java @@ -0,0 +1,130 @@ +package com.zzyl.generator.service; + +import java.util.List; +import java.util.Map; +import com.zzyl.generator.domain.GenTable; + +/** + * 业务 服务层 + * + * @author ruoyi + */ +public interface IGenTableService +{ + /** + * 查询业务列表 + * + * @param genTable 业务信息 + * @return 业务集合 + */ + public List selectGenTableList(GenTable genTable); + + /** + * 查询据库列表 + * + * @param genTable 业务信息 + * @return 数据库表集合 + */ + public List selectDbTableList(GenTable genTable); + + /** + * 查询据库列表 + * + * @param tableNames 表名称组 + * @return 数据库表集合 + */ + public List selectDbTableListByNames(String[] tableNames); + + /** + * 查询所有表信息 + * + * @return 表信息集合 + */ + public List selectGenTableAll(); + + /** + * 查询业务信息 + * + * @param id 业务ID + * @return 业务信息 + */ + public GenTable selectGenTableById(Long id); + + /** + * 修改业务 + * + * @param genTable 业务信息 + * @return 结果 + */ + public void updateGenTable(GenTable genTable); + + /** + * 删除业务信息 + * + * @param tableIds 需要删除的表数据ID + * @return 结果 + */ + public void deleteGenTableByIds(Long[] tableIds); + + /** + * 创建表 + * + * @param sql 创建表语句 + * @return 结果 + */ + public boolean createTable(String sql); + + /** + * 导入表结构 + * + * @param tableList 导入表列表 + * @param operName 操作人员 + */ + public void importGenTable(List tableList, String operName); + + /** + * 预览代码 + * + * @param tableId 表编号 + * @return 预览数据列表 + */ + public Map previewCode(Long tableId); + + /** + * 生成代码(下载方式) + * + * @param tableName 表名称 + * @return 数据 + */ + public byte[] downloadCode(String tableName); + + /** + * 生成代码(自定义路径) + * + * @param tableName 表名称 + * @return 数据 + */ + public void generatorCode(String tableName); + + /** + * 同步数据库 + * + * @param tableName 表名称 + */ + public void synchDb(String tableName); + + /** + * 批量生成代码(下载方式) + * + * @param tableNames 表数组 + * @return 数据 + */ + public byte[] downloadCode(String[] tableNames); + + /** + * 修改保存参数校验 + * + * @param genTable 业务信息 + */ + public void validateEdit(GenTable genTable); +} diff --git a/zzyl-generator/src/main/java/com/zzyl/generator/util/GenUtils.java b/zzyl-generator/src/main/java/com/zzyl/generator/util/GenUtils.java new file mode 100644 index 0000000..2ce1477 --- /dev/null +++ b/zzyl-generator/src/main/java/com/zzyl/generator/util/GenUtils.java @@ -0,0 +1,258 @@ +package com.zzyl.generator.util; + +import java.util.Arrays; +import org.apache.commons.lang3.RegExUtils; +import com.zzyl.common.constant.GenConstants; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.generator.config.GenConfig; +import com.zzyl.generator.domain.GenTable; +import com.zzyl.generator.domain.GenTableColumn; + +/** + * 代码生成器 工具类 + * + * @author ruoyi + */ +public class GenUtils +{ + /** + * 初始化表信息 + */ + public static void initTable(GenTable genTable, String operName) + { + genTable.setClassName(convertClassName(genTable.getTableName())); + genTable.setPackageName(GenConfig.getPackageName()); + genTable.setModuleName(getModuleName(GenConfig.getPackageName())); + genTable.setBusinessName(getBusinessName(genTable.getTableName())); + genTable.setFunctionName(replaceText(genTable.getTableComment())); + genTable.setFunctionAuthor(GenConfig.getAuthor()); + genTable.setCreateBy(operName); + } + + /** + * 初始化列属性字段 + */ + public static void initColumnField(GenTableColumn column, GenTable table) + { + String dataType = getDbType(column.getColumnType()); + String columnName = column.getColumnName(); + column.setTableId(table.getTableId()); + column.setCreateBy(table.getCreateBy()); + // 设置java字段名 + column.setJavaField(StringUtils.toCamelCase(columnName)); + // 设置默认类型 + column.setJavaType(GenConstants.TYPE_STRING); + column.setQueryType(GenConstants.QUERY_EQ); + + if (arraysContains(GenConstants.COLUMNTYPE_STR, dataType) || arraysContains(GenConstants.COLUMNTYPE_TEXT, dataType)) + { + // 字符串长度超过500设置为文本域 + Integer columnLength = getColumnLength(column.getColumnType()); + String htmlType = columnLength >= 500 || arraysContains(GenConstants.COLUMNTYPE_TEXT, dataType) ? GenConstants.HTML_TEXTAREA : GenConstants.HTML_INPUT; + column.setHtmlType(htmlType); + } + else if (arraysContains(GenConstants.COLUMNTYPE_TIME, dataType)) + { + column.setJavaType(GenConstants.TYPE_LOCAL_DATE_TIME); + column.setHtmlType(GenConstants.HTML_DATETIME); + } + else if (arraysContains(GenConstants.COLUMNTYPE_NUMBER, dataType)) + { + column.setHtmlType(GenConstants.HTML_INPUT); + + // 如果是浮点型 统一用BigDecimal + String[] str = StringUtils.split(StringUtils.substringBetween(column.getColumnType(), "(", ")"), ","); + if (str != null && str.length == 2 && Integer.parseInt(str[1]) > 0) + { + column.setJavaType(GenConstants.TYPE_BIGDECIMAL); + } + // 如果是整形 + else if (str != null && str.length == 1 && Integer.parseInt(str[0]) <= 10 + || GenConstants.MYSQL_TINYINT.equals(column.getColumnType()) || GenConstants.MYSQL_INT.equals(column.getColumnType())) + { + column.setJavaType(GenConstants.TYPE_INTEGER); + } + // 长整形 + else + { + column.setJavaType(GenConstants.TYPE_LONG); + } + } + + // 插入字段(默认所有字段都需要插入) + column.setIsInsert(GenConstants.REQUIRE); + + // 编辑字段 + if (!arraysContains(GenConstants.COLUMNNAME_NOT_EDIT, columnName) && !column.isPk()) + { + column.setIsEdit(GenConstants.REQUIRE); + } + // 列表字段 + if (!arraysContains(GenConstants.COLUMNNAME_NOT_LIST, columnName) && !column.isPk()) + { + column.setIsList(GenConstants.REQUIRE); + } + // 查询字段 + if (!arraysContains(GenConstants.COLUMNNAME_NOT_QUERY, columnName) && !column.isPk()) + { + column.setIsQuery(GenConstants.REQUIRE); + } + + // 查询字段类型 + if (StringUtils.endsWithIgnoreCase(columnName, "name")) + { + column.setQueryType(GenConstants.QUERY_LIKE); + } + // 状态字段设置单选框 + if (StringUtils.endsWithIgnoreCase(columnName, "status")) + { + column.setHtmlType(GenConstants.HTML_RADIO); + } + // 类型&性别字段设置下拉框 + else if (StringUtils.endsWithIgnoreCase(columnName, "type") + || StringUtils.endsWithIgnoreCase(columnName, "sex")) + { + column.setHtmlType(GenConstants.HTML_SELECT); + } + // 图片字段设置图片上传控件 + else if (StringUtils.endsWithIgnoreCase(columnName, "image")) + { + column.setHtmlType(GenConstants.HTML_IMAGE_UPLOAD); + } + // 文件字段设置文件上传控件 + else if (StringUtils.endsWithIgnoreCase(columnName, "file")) + { + column.setHtmlType(GenConstants.HTML_FILE_UPLOAD); + } + // 内容字段设置富文本控件 + else if (StringUtils.endsWithIgnoreCase(columnName, "content")) + { + column.setHtmlType(GenConstants.HTML_EDITOR); + } + } + + /** + * 校验数组是否包含指定值 + * + * @param arr 数组 + * @param targetValue 值 + * @return 是否包含 + */ + public static boolean arraysContains(String[] arr, String targetValue) + { + return Arrays.asList(arr).contains(targetValue); + } + + /** + * 获取模块名 + * + * @param packageName 包名 + * @return 模块名 + */ + public static String getModuleName(String packageName) + { + int lastIndex = packageName.lastIndexOf("."); + int nameLength = packageName.length(); + return StringUtils.substring(packageName, lastIndex + 1, nameLength); + } + + /** + * 获取业务名 + * + * @param tableName 表名 + * @return 业务名 + */ + public static String getBusinessName(String tableName) + { + int lastIndex = tableName.lastIndexOf("_"); + int nameLength = tableName.length(); + return StringUtils.substring(tableName, lastIndex + 1, nameLength); + } + + /** + * 表名转换成Java类名 + * + * @param tableName 表名称 + * @return 类名 + */ + public static String convertClassName(String tableName) + { + boolean autoRemovePre = GenConfig.getAutoRemovePre(); + String tablePrefix = GenConfig.getTablePrefix(); + if (autoRemovePre && StringUtils.isNotEmpty(tablePrefix)) + { + String[] searchList = StringUtils.split(tablePrefix, ","); + tableName = replaceFirst(tableName, searchList); + } + return StringUtils.convertToCamelCase(tableName); + } + + /** + * 批量替换前缀 + * + * @param replacementm 替换值 + * @param searchList 替换列表 + * @return + */ + public static String replaceFirst(String replacementm, String[] searchList) + { + String text = replacementm; + for (String searchString : searchList) + { + if (replacementm.startsWith(searchString)) + { + text = replacementm.replaceFirst(searchString, ""); + break; + } + } + return text; + } + + /** + * 关键字替换 + * + * @param text 需要被替换的名字 + * @return 替换后的名字 + */ + public static String replaceText(String text) + { + return RegExUtils.replaceAll(text, "(?:表|若依)", ""); + } + + /** + * 获取数据库类型字段 + * + * @param columnType 列类型 + * @return 截取后的列类型 + */ + public static String getDbType(String columnType) + { + if (StringUtils.indexOf(columnType, "(") > 0) + { + return StringUtils.substringBefore(columnType, "("); + } + else + { + return columnType; + } + } + + /** + * 获取字段长度 + * + * @param columnType 列类型 + * @return 截取后的列类型 + */ + public static Integer getColumnLength(String columnType) + { + if (StringUtils.indexOf(columnType, "(") > 0) + { + String length = StringUtils.substringBetween(columnType, "(", ")"); + return Integer.valueOf(length); + } + else + { + return 0; + } + } +} diff --git a/zzyl-generator/src/main/java/com/zzyl/generator/util/VelocityInitializer.java b/zzyl-generator/src/main/java/com/zzyl/generator/util/VelocityInitializer.java new file mode 100644 index 0000000..aa766d8 --- /dev/null +++ b/zzyl-generator/src/main/java/com/zzyl/generator/util/VelocityInitializer.java @@ -0,0 +1,34 @@ +package com.zzyl.generator.util; + +import java.util.Properties; +import org.apache.velocity.app.Velocity; +import com.zzyl.common.constant.Constants; + +/** + * VelocityEngine工厂 + * + * @author ruoyi + */ +public class VelocityInitializer +{ + /** + * 初始化vm方法 + */ + public static void initVelocity() + { + Properties p = new Properties(); + try + { + // 加载classpath目录下的vm文件 + p.setProperty("resource.loader.file.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); + // 定义字符集 + p.setProperty(Velocity.INPUT_ENCODING, Constants.UTF8); + // 初始化Velocity引擎,指定配置Properties + Velocity.init(p); + } + catch (Exception e) + { + throw new RuntimeException(e); + } + } +} diff --git a/zzyl-generator/src/main/java/com/zzyl/generator/util/VelocityUtils.java b/zzyl-generator/src/main/java/com/zzyl/generator/util/VelocityUtils.java new file mode 100644 index 0000000..755f46f --- /dev/null +++ b/zzyl-generator/src/main/java/com/zzyl/generator/util/VelocityUtils.java @@ -0,0 +1,414 @@ +package com.zzyl.generator.util; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.apache.velocity.VelocityContext; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.zzyl.common.constant.GenConstants; +import com.zzyl.common.utils.DateUtils; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.generator.domain.GenTable; +import com.zzyl.generator.domain.GenTableColumn; + +/** + * 模板处理工具类 + * + * @author ruoyi + */ +public class VelocityUtils +{ + /** 项目空间路径 */ + private static final String PROJECT_PATH = "main/java"; + + /** mybatis空间路径 */ + private static final String MYBATIS_PATH = "main/resources/mapper"; + + /** 默认上级菜单,系统工具 */ + private static final String DEFAULT_PARENT_MENU_ID = "3"; + + /** + * 设置模板变量信息 + * + * @return 模板列表 + */ + public static VelocityContext prepareContext(GenTable genTable) + { + String moduleName = genTable.getModuleName(); + String businessName = genTable.getBusinessName(); + String packageName = genTable.getPackageName(); + String tplCategory = genTable.getTplCategory(); + String functionName = genTable.getFunctionName(); + + VelocityContext velocityContext = new VelocityContext(); + velocityContext.put("tplCategory", genTable.getTplCategory()); + velocityContext.put("tableName", genTable.getTableName()); + velocityContext.put("functionName", StringUtils.isNotEmpty(functionName) ? functionName : "【请填写功能名称】"); + velocityContext.put("ClassName", genTable.getClassName()); + velocityContext.put("className", StringUtils.uncapitalize(genTable.getClassName())); + velocityContext.put("moduleName", genTable.getModuleName()); + velocityContext.put("BusinessName", StringUtils.capitalize(genTable.getBusinessName())); + velocityContext.put("businessName", genTable.getBusinessName()); + velocityContext.put("basePackage", getPackagePrefix(packageName)); + velocityContext.put("packageName", packageName); + velocityContext.put("author", genTable.getFunctionAuthor()); + velocityContext.put("datetime", DateUtils.getDate()); + velocityContext.put("pkColumn", genTable.getPkColumn()); + velocityContext.put("importList", getImportList(genTable)); + velocityContext.put("permissionPrefix", getPermissionPrefix(moduleName, businessName)); + velocityContext.put("columns", genTable.getColumns()); + velocityContext.put("table", genTable); + velocityContext.put("dicts", getDicts(genTable)); + setMenuVelocityContext(velocityContext, genTable); + if (GenConstants.TPL_TREE.equals(tplCategory)) + { + setTreeVelocityContext(velocityContext, genTable); + } + if (GenConstants.TPL_SUB.equals(tplCategory)) + { + setSubVelocityContext(velocityContext, genTable); + } + return velocityContext; + } + + public static void setMenuVelocityContext(VelocityContext context, GenTable genTable) + { + String options = genTable.getOptions(); + JSONObject paramsObj = JSON.parseObject(options); + String parentMenuId = getParentMenuId(paramsObj); + context.put("parentMenuId", parentMenuId); + } + + public static void setTreeVelocityContext(VelocityContext context, GenTable genTable) + { + String options = genTable.getOptions(); + JSONObject paramsObj = JSON.parseObject(options); + String treeCode = getTreecode(paramsObj); + String treeParentCode = getTreeParentCode(paramsObj); + String treeName = getTreeName(paramsObj); + + context.put("treeCode", treeCode); + context.put("treeParentCode", treeParentCode); + context.put("treeName", treeName); + context.put("expandColumn", getExpandColumn(genTable)); + if (paramsObj.containsKey(GenConstants.TREE_PARENT_CODE)) + { + context.put("tree_parent_code", paramsObj.getString(GenConstants.TREE_PARENT_CODE)); + } + if (paramsObj.containsKey(GenConstants.TREE_NAME)) + { + context.put("tree_name", paramsObj.getString(GenConstants.TREE_NAME)); + } + } + + public static void setSubVelocityContext(VelocityContext context, GenTable genTable) + { + GenTable subTable = genTable.getSubTable(); + String subTableName = genTable.getSubTableName(); + String subTableFkName = genTable.getSubTableFkName(); + String subClassName = genTable.getSubTable().getClassName(); + String subTableFkClassName = StringUtils.convertToCamelCase(subTableFkName); + + context.put("subTable", subTable); + context.put("subTableName", subTableName); + context.put("subTableFkName", subTableFkName); + context.put("subTableFkClassName", subTableFkClassName); + context.put("subTableFkclassName", StringUtils.uncapitalize(subTableFkClassName)); + context.put("subClassName", subClassName); + context.put("subclassName", StringUtils.uncapitalize(subClassName)); + context.put("subImportList", getImportList(genTable.getSubTable())); + } + + /** + * 获取模板信息 + * @param tplCategory 生成的模板 + * @param tplWebType 前端类型 + * @return 模板列表 + */ + public static List getTemplateList(String tplCategory, String tplWebType) + { + String useWebType = "vm/vue"; + if ("element-plus".equals(tplWebType)) + { + useWebType = "vm/vue/v3"; + } + List templates = new ArrayList(); + templates.add("vm/java/domain.java.vm"); + templates.add("vm/java/mapper.java.vm"); + templates.add("vm/java/service.java.vm"); + templates.add("vm/java/serviceImpl.java.vm"); + templates.add("vm/java/controller.java.vm"); + templates.add("vm/xml/mapper.xml.vm"); + templates.add("vm/sql/sql.vm"); + templates.add("vm/js/api.js.vm"); + if (GenConstants.TPL_CRUD.equals(tplCategory)) + { + templates.add(useWebType + "/index.vue.vm"); + } + else if (GenConstants.TPL_TREE.equals(tplCategory)) + { + templates.add(useWebType + "/index-tree.vue.vm"); + } + else if (GenConstants.TPL_SUB.equals(tplCategory)) + { + templates.add(useWebType + "/index.vue.vm"); + templates.add("vm/java/sub-domain.java.vm"); + } + return templates; + } + + /** + * 获取文件名 + */ + public static String getFileName(String template, GenTable genTable) + { + // 文件名称 + String fileName = ""; + // 包路径 + String packageName = genTable.getPackageName(); + // 模块名 + String moduleName = genTable.getModuleName(); + // 大写类名 + String className = genTable.getClassName(); + // 业务名称 + String businessName = genTable.getBusinessName(); + + String javaPath = PROJECT_PATH + "/" + StringUtils.replace(packageName, ".", "/"); + String mybatisPath = MYBATIS_PATH + "/" + moduleName; + String vuePath = "vue"; + + if (template.contains("domain.java.vm")) + { + fileName = StringUtils.format("{}/domain/{}.java", javaPath, className); + } + if (template.contains("sub-domain.java.vm") && StringUtils.equals(GenConstants.TPL_SUB, genTable.getTplCategory())) + { + fileName = StringUtils.format("{}/domain/{}.java", javaPath, genTable.getSubTable().getClassName()); + } + else if (template.contains("mapper.java.vm")) + { + fileName = StringUtils.format("{}/mapper/{}Mapper.java", javaPath, className); + } + else if (template.contains("service.java.vm")) + { + fileName = StringUtils.format("{}/service/I{}Service.java", javaPath, className); + } + else if (template.contains("serviceImpl.java.vm")) + { + fileName = StringUtils.format("{}/service/impl/{}ServiceImpl.java", javaPath, className); + } + else if (template.contains("controller.java.vm")) + { + fileName = StringUtils.format("{}/controller/{}Controller.java", javaPath, className); + } + else if (template.contains("mapper.xml.vm")) + { + fileName = StringUtils.format("{}/{}Mapper.xml", mybatisPath, className); + } + else if (template.contains("sql.vm")) + { + fileName = businessName + "Menu.sql"; + } + else if (template.contains("api.js.vm")) + { + fileName = StringUtils.format("{}/api/{}/{}.js", vuePath, moduleName, businessName); + } + else if (template.contains("index.vue.vm")) + { + fileName = StringUtils.format("{}/views/{}/{}/index.vue", vuePath, moduleName, businessName); + } + else if (template.contains("index-tree.vue.vm")) + { + fileName = StringUtils.format("{}/views/{}/{}/index.vue", vuePath, moduleName, businessName); + } + return fileName; + } + + /** + * 获取包前缀 + * + * @param packageName 包名称 + * @return 包前缀名称 + */ + public static String getPackagePrefix(String packageName) + { + int lastIndex = packageName.lastIndexOf("."); + return StringUtils.substring(packageName, 0, lastIndex); + } + + /** + * 根据列类型获取导入包 + * + * @param genTable 业务表对象 + * @return 返回需要导入的包列表 + */ + public static HashSet getImportList(GenTable genTable) + { + List columns = genTable.getColumns(); + GenTable subGenTable = genTable.getSubTable(); + HashSet importList = new HashSet(); + if (StringUtils.isNotNull(subGenTable)) + { + importList.add("java.util.List"); + } + for (GenTableColumn column : columns) + { + if (!column.isSuperColumn() && GenConstants.TYPE_DATE.equals(column.getJavaType())) + { + importList.add("java.util.Date"); + importList.add("com.fasterxml.jackson.annotation.JsonFormat"); + } + else if (!column.isSuperColumn() && GenConstants.TYPE_LOCAL_DATE_TIME.equals(column.getJavaType())) + { + importList.add("java.time.LocalDateTime"); + // 导入这个是为了格式化日期 + importList.add("com.fasterxml.jackson.annotation.JsonFormat"); + } + else if (!column.isSuperColumn() && GenConstants.TYPE_BIGDECIMAL.equals(column.getJavaType())) + { + importList.add("java.math.BigDecimal"); + } + } + return importList; + } + + /** + * 根据列类型获取字典组 + * + * @param genTable 业务表对象 + * @return 返回字典组 + */ + public static String getDicts(GenTable genTable) + { + List columns = genTable.getColumns(); + Set dicts = new HashSet(); + addDicts(dicts, columns); + if (StringUtils.isNotNull(genTable.getSubTable())) + { + List subColumns = genTable.getSubTable().getColumns(); + addDicts(dicts, subColumns); + } + return StringUtils.join(dicts, ", "); + } + + /** + * 添加字典列表 + * + * @param dicts 字典列表 + * @param columns 列集合 + */ + public static void addDicts(Set dicts, List columns) + { + for (GenTableColumn column : columns) + { + if (!column.isSuperColumn() && StringUtils.isNotEmpty(column.getDictType()) && StringUtils.equalsAny( + column.getHtmlType(), + new String[] { GenConstants.HTML_SELECT, GenConstants.HTML_RADIO, GenConstants.HTML_CHECKBOX })) + { + dicts.add("'" + column.getDictType() + "'"); + } + } + } + + /** + * 获取权限前缀 + * + * @param moduleName 模块名称 + * @param businessName 业务名称 + * @return 返回权限前缀 + */ + public static String getPermissionPrefix(String moduleName, String businessName) + { + return StringUtils.format("{}:{}", moduleName, businessName); + } + + /** + * 获取上级菜单ID字段 + * + * @param paramsObj 生成其他选项 + * @return 上级菜单ID字段 + */ + public static String getParentMenuId(JSONObject paramsObj) + { + if (StringUtils.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.PARENT_MENU_ID) + && StringUtils.isNotEmpty(paramsObj.getString(GenConstants.PARENT_MENU_ID))) + { + return paramsObj.getString(GenConstants.PARENT_MENU_ID); + } + return DEFAULT_PARENT_MENU_ID; + } + + /** + * 获取树编码 + * + * @param paramsObj 生成其他选项 + * @return 树编码 + */ + public static String getTreecode(JSONObject paramsObj) + { + if (paramsObj.containsKey(GenConstants.TREE_CODE)) + { + return StringUtils.toCamelCase(paramsObj.getString(GenConstants.TREE_CODE)); + } + return StringUtils.EMPTY; + } + + /** + * 获取树父编码 + * + * @param paramsObj 生成其他选项 + * @return 树父编码 + */ + public static String getTreeParentCode(JSONObject paramsObj) + { + if (paramsObj.containsKey(GenConstants.TREE_PARENT_CODE)) + { + return StringUtils.toCamelCase(paramsObj.getString(GenConstants.TREE_PARENT_CODE)); + } + return StringUtils.EMPTY; + } + + /** + * 获取树名称 + * + * @param paramsObj 生成其他选项 + * @return 树名称 + */ + public static String getTreeName(JSONObject paramsObj) + { + if (paramsObj.containsKey(GenConstants.TREE_NAME)) + { + return StringUtils.toCamelCase(paramsObj.getString(GenConstants.TREE_NAME)); + } + return StringUtils.EMPTY; + } + + /** + * 获取需要在哪一列上面显示展开按钮 + * + * @param genTable 业务表对象 + * @return 展开按钮列序号 + */ + public static int getExpandColumn(GenTable genTable) + { + String options = genTable.getOptions(); + JSONObject paramsObj = JSON.parseObject(options); + String treeName = paramsObj.getString(GenConstants.TREE_NAME); + int num = 0; + for (GenTableColumn column : genTable.getColumns()) + { + if (column.isList()) + { + num++; + String columnName = column.getColumnName(); + if (columnName.equals(treeName)) + { + break; + } + } + } + return num; + } +} diff --git a/zzyl-generator/src/main/resources/generator.yml b/zzyl-generator/src/main/resources/generator.yml new file mode 100644 index 0000000..8148484 --- /dev/null +++ b/zzyl-generator/src/main/resources/generator.yml @@ -0,0 +1,12 @@ +# 代码生成 +gen: + # 作者 + author: Zhy + # 默认生成包路径 system 需改成自己的模块名称 如 system monitor tool + packageName: com.zzyl.nursing + # 自动去除表前缀,默认是false + autoRemovePre: false + # 表前缀(生成类名不会包含表前缀,多个用逗号分隔) + tablePrefix: sys_ + # 是否允许生成文件覆盖到本地(自定义路径),默认不允许 + allowOverwrite: false \ No newline at end of file diff --git a/zzyl-generator/src/main/resources/mapper/generator/GenTableColumnMapper.xml b/zzyl-generator/src/main/resources/mapper/generator/GenTableColumnMapper.xml new file mode 100644 index 0000000..11f251a --- /dev/null +++ b/zzyl-generator/src/main/resources/mapper/generator/GenTableColumnMapper.xml @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select column_id, table_id, column_name, column_comment, column_type, java_type, java_field, is_pk, is_increment, is_required, is_insert, is_edit, is_list, is_query, query_type, html_type, dict_type, sort, create_by, create_time, update_by, update_time from gen_table_column + + + + + + + + insert into gen_table_column ( + table_id, + column_name, + column_comment, + column_type, + java_type, + java_field, + is_pk, + is_increment, + is_required, + is_insert, + is_edit, + is_list, + is_query, + query_type, + html_type, + dict_type, + sort, + create_by, + create_time + )values( + #{tableId}, + #{columnName}, + #{columnComment}, + #{columnType}, + #{javaType}, + #{javaField}, + #{isPk}, + #{isIncrement}, + #{isRequired}, + #{isInsert}, + #{isEdit}, + #{isList}, + #{isQuery}, + #{queryType}, + #{htmlType}, + #{dictType}, + #{sort}, + #{createBy}, + sysdate() + ) + + + + update gen_table_column + + column_comment = #{columnComment}, + java_type = #{javaType}, + java_field = #{javaField}, + is_insert = #{isInsert}, + is_edit = #{isEdit}, + is_list = #{isList}, + is_query = #{isQuery}, + is_required = #{isRequired}, + query_type = #{queryType}, + html_type = #{htmlType}, + dict_type = #{dictType}, + sort = #{sort}, + update_by = #{updateBy}, + update_time = sysdate() + + where column_id = #{columnId} + + + + delete from gen_table_column where table_id in + + #{tableId} + + + + + delete from gen_table_column where column_id in + + #{item.columnId} + + + + \ No newline at end of file diff --git a/zzyl-generator/src/main/resources/mapper/generator/GenTableMapper.xml b/zzyl-generator/src/main/resources/mapper/generator/GenTableMapper.xml new file mode 100644 index 0000000..15ade7a --- /dev/null +++ b/zzyl-generator/src/main/resources/mapper/generator/GenTableMapper.xml @@ -0,0 +1,210 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select table_id, table_name, table_comment, sub_table_name, sub_table_fk_name, class_name, tpl_category, tpl_web_type, package_name, module_name, business_name, function_name, function_author, gen_type, gen_path, options, create_by, create_time, update_by, update_time, remark from gen_table + + + + + + + + + + + + + + + + + + insert into gen_table ( + table_name, + table_comment, + class_name, + tpl_category, + tpl_web_type, + package_name, + module_name, + business_name, + function_name, + function_author, + gen_type, + gen_path, + remark, + create_by, + create_time + )values( + #{tableName}, + #{tableComment}, + #{className}, + #{tplCategory}, + #{tplWebType}, + #{packageName}, + #{moduleName}, + #{businessName}, + #{functionName}, + #{functionAuthor}, + #{genType}, + #{genPath}, + #{remark}, + #{createBy}, + sysdate() + ) + + + + ${sql} + + + + update gen_table + + table_name = #{tableName}, + table_comment = #{tableComment}, + sub_table_name = #{subTableName}, + sub_table_fk_name = #{subTableFkName}, + class_name = #{className}, + function_author = #{functionAuthor}, + gen_type = #{genType}, + gen_path = #{genPath}, + tpl_category = #{tplCategory}, + tpl_web_type = #{tplWebType}, + package_name = #{packageName}, + module_name = #{moduleName}, + business_name = #{businessName}, + function_name = #{functionName}, + options = #{options}, + update_by = #{updateBy}, + remark = #{remark}, + update_time = sysdate() + + where table_id = #{tableId} + + + + delete from gen_table where table_id in + + #{tableId} + + + + \ No newline at end of file diff --git a/zzyl-generator/src/main/resources/vm/java/controller.java.vm b/zzyl-generator/src/main/resources/vm/java/controller.java.vm new file mode 100644 index 0000000..f1b2f6e --- /dev/null +++ b/zzyl-generator/src/main/resources/vm/java/controller.java.vm @@ -0,0 +1,127 @@ +package ${packageName}.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; + +import com.zzyl.common.core.domain.R; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.zzyl.common.annotation.Log; +import com.zzyl.common.core.controller.BaseController; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.enums.BusinessType; +import ${packageName}.domain.${ClassName}; +import ${packageName}.service.I${ClassName}Service; +import com.zzyl.common.utils.poi.ExcelUtil; +#if($table.crud || $table.sub) +import com.zzyl.common.core.page.TableDataInfo; +#elseif($table.tree) +#end + +/** + * ${functionName}Controller + * + * @author ${author} + * @date ${datetime} + */ +@Api(tags = "${functionName}管理") +@RestController +@RequestMapping("/${moduleName}/${businessName}") +public class ${ClassName}Controller extends BaseController +{ + @Autowired + private I${ClassName}Service ${className}Service; + + /** + * 查询${functionName}列表 + */ + @ApiOperation("查询${functionName}列表") + @PreAuthorize("@ss.hasPermi('${permissionPrefix}:list')") + @GetMapping("/list") +#if($table.crud || $table.sub) + public TableDataInfo> list(@ApiParam("${functionName}查询条件") ${ClassName} ${className}) + { + startPage(); + List<${ClassName}> list = ${className}Service.select${ClassName}List(${className}); + return getDataTable(list); + } +#elseif($table.tree) + public AjaxResult list(${ClassName} ${className}) + { + List<${ClassName}> list = ${className}Service.select${ClassName}List(${className}); + return success(list); + } +#end + + /** + * 导出${functionName}列表 + */ + @ApiOperation("导出${functionName}列表") + @PreAuthorize("@ss.hasPermi('${permissionPrefix}:export')") + @Log(title = "${functionName}", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(@ApiParam(value = "${functionName}查询条件") HttpServletResponse response, ${ClassName} ${className}) + { + List<${ClassName}> list = ${className}Service.select${ClassName}List(${className}); + ExcelUtil<${ClassName}> util = new ExcelUtil<${ClassName}>(${ClassName}.class); + util.exportExcel(response, list, "${functionName}数据"); + } + + /** + * 获取${functionName}详细信息 + */ + @ApiOperation("获取${functionName}详细信息") + @PreAuthorize("@ss.hasPermi('${permissionPrefix}:query')") + @GetMapping(value = "/{${pkColumn.javaField}}") + public R<${ClassName}> getInfo(@ApiParam("${functionName}ID") @PathVariable("${pkColumn.javaField}") ${pkColumn.javaType} ${pkColumn.javaField}) + { + return R.ok(${className}Service.select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaField})); + } + + /** + * 新增${functionName} + */ + @ApiOperation("新增${functionName}") + @PreAuthorize("@ss.hasPermi('${permissionPrefix}:add')") + @Log(title = "${functionName}", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@ApiParam("${functionName}信息") @RequestBody ${ClassName} ${className}) + { + return toAjax(${className}Service.insert${ClassName}(${className})); + } + + /** + * 修改${functionName} + */ + @ApiOperation("修改${functionName}") + @PreAuthorize("@ss.hasPermi('${permissionPrefix}:edit')") + @Log(title = "${functionName}", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@ApiParam("${functionName}信息") @RequestBody ${ClassName} ${className}) + { + return toAjax(${className}Service.update${ClassName}(${className})); + } + + /** + * 删除${functionName} + */ + @ApiOperation("删除${functionName}") + @PreAuthorize("@ss.hasPermi('${permissionPrefix}:remove')") + @Log(title = "${functionName}", businessType = BusinessType.DELETE) + @DeleteMapping("/{${pkColumn.javaField}s}") + public AjaxResult remove(@ApiParam("${functionName}ID数组") @PathVariable ${pkColumn.javaType}[] ${pkColumn.javaField}s) + { + return toAjax(${className}Service.delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaField}s)); + } +} diff --git a/zzyl-generator/src/main/resources/vm/java/domain.java.vm b/zzyl-generator/src/main/resources/vm/java/domain.java.vm new file mode 100644 index 0000000..8e5a843 --- /dev/null +++ b/zzyl-generator/src/main/resources/vm/java/domain.java.vm @@ -0,0 +1,77 @@ +package ${packageName}.domain; + +#foreach ($import in $importList) +import ${import}; +#end +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.AllArgsConstructor; +import com.zzyl.common.annotation.Excel; +#if($table.crud || $table.sub) +import com.zzyl.common.core.domain.BaseEntity; +#elseif($table.tree) +import com.zzyl.common.core.domain.TreeEntity; +#end + +/** + * ${functionName}对象 ${tableName} + * + * @author ${author} + * @date ${datetime} + */ +#if($table.crud || $table.sub) +#set($Entity="BaseEntity") +#elseif($table.tree) +#set($Entity="TreeEntity") +#end +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel("${functionName}实体") +public class ${ClassName} extends ${Entity} +{ + private static final long serialVersionUID = 1L; + +#foreach ($column in $columns) +#if(!$table.isSuperColumn($column.javaField)) + // $column.columnComment +#if($column.list) +#set($parentheseIndex=$column.columnComment.indexOf("(")) +#if($parentheseIndex != -1) +#set($comment=$column.columnComment.substring(0, $parentheseIndex)) +#else +#set($comment=$column.columnComment) +#end +#if($parentheseIndex != -1) + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") +#elseif($column.javaType == 'Date' || $column.javaType == 'LocalDateTime') + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "${comment}", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") +#else + @Excel(name = "${comment}") +#end +#end + @ApiModelProperty("${column.columnComment}") + private $column.javaType $column.javaField; + +#end +#end +#if($table.sub) + /** $table.subTable.functionName信息 */ + private List<${subClassName}> ${subclassName}List; + +#end +#if($table.sub) + public List<${subClassName}> get${subClassName}List() + { + return ${subclassName}List; + } + + public void set${subClassName}List(List<${subClassName}> ${subclassName}List) + { + this.${subclassName}List = ${subclassName}List; + } +#end +} diff --git a/zzyl-generator/src/main/resources/vm/java/mapper.java.vm b/zzyl-generator/src/main/resources/vm/java/mapper.java.vm new file mode 100644 index 0000000..5db0bad --- /dev/null +++ b/zzyl-generator/src/main/resources/vm/java/mapper.java.vm @@ -0,0 +1,94 @@ +package ${packageName}.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import java.util.List; +import ${packageName}.domain.${ClassName}; +#if($table.sub) +import ${packageName}.domain.${subClassName}; +#end + +/** + * ${functionName}Mapper接口 + * + * @author ${author} + * @date ${datetime} + */ +@Mapper +public interface ${ClassName}Mapper extends BaseMapper<${ClassName}> +{ + /** + * 查询${functionName} + * + * @param ${pkColumn.javaField} ${functionName}主键 + * @return ${functionName} + */ + public ${ClassName} select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}); + + /** + * 查询${functionName}列表 + * + * @param ${className} ${functionName} + * @return ${functionName}集合 + */ + public List<${ClassName}> select${ClassName}List(${ClassName} ${className}); + + /** + * 新增${functionName} + * + * @param ${className} ${functionName} + * @return 结果 + */ + public int insert${ClassName}(${ClassName} ${className}); + + /** + * 修改${functionName} + * + * @param ${className} ${functionName} + * @return 结果 + */ + public int update${ClassName}(${ClassName} ${className}); + + /** + * 删除${functionName} + * + * @param ${pkColumn.javaField} ${functionName}主键 + * @return 结果 + */ + public int delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}); + + /** + * 批量删除${functionName} + * + * @param ${pkColumn.javaField}s 需要删除的数据主键集合 + * @return 结果 + */ + public int delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaType}[] ${pkColumn.javaField}s); +#if($table.sub) + + /** + * 批量删除${subTable.functionName} + * + * @param ${pkColumn.javaField}s 需要删除的数据主键集合 + * @return 结果 + */ + public int delete${subClassName}By${subTableFkClassName}s(${pkColumn.javaType}[] ${pkColumn.javaField}s); + + /** + * 批量新增${subTable.functionName} + * + * @param ${subclassName}List ${subTable.functionName}列表 + * @return 结果 + */ + public int batch${subClassName}(List<${subClassName}> ${subclassName}List); + + + /** + * 通过${functionName}主键删除${subTable.functionName}信息 + * + * @param ${pkColumn.javaField} ${functionName}ID + * @return 结果 + */ + public int delete${subClassName}By${subTableFkClassName}(${pkColumn.javaType} ${pkColumn.javaField}); +#end +} diff --git a/zzyl-generator/src/main/resources/vm/java/service.java.vm b/zzyl-generator/src/main/resources/vm/java/service.java.vm new file mode 100644 index 0000000..1911621 --- /dev/null +++ b/zzyl-generator/src/main/resources/vm/java/service.java.vm @@ -0,0 +1,62 @@ +package ${packageName}.service; + +import java.util.List; +import ${packageName}.domain.${ClassName}; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + * ${functionName}Service接口 + * + * @author ${author} + * @date ${datetime} + */ +public interface I${ClassName}Service extends IService<${ClassName}> +{ + /** + * 查询${functionName} + * + * @param ${pkColumn.javaField} ${functionName}主键 + * @return ${functionName} + */ + public ${ClassName} select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}); + + /** + * 查询${functionName}列表 + * + * @param ${className} ${functionName} + * @return ${functionName}集合 + */ + public List<${ClassName}> select${ClassName}List(${ClassName} ${className}); + + /** + * 新增${functionName} + * + * @param ${className} ${functionName} + * @return 结果 + */ + public int insert${ClassName}(${ClassName} ${className}); + + /** + * 修改${functionName} + * + * @param ${className} ${functionName} + * @return 结果 + */ + public int update${ClassName}(${ClassName} ${className}); + + /** + * 批量删除${functionName} + * + * @param ${pkColumn.javaField}s 需要删除的${functionName}主键集合 + * @return 结果 + */ + public int delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaType}[] ${pkColumn.javaField}s); + + /** + * 删除${functionName}信息 + * + * @param ${pkColumn.javaField} ${functionName}主键 + * @return 结果 + */ + public int delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}); +} diff --git a/zzyl-generator/src/main/resources/vm/java/serviceImpl.java.vm b/zzyl-generator/src/main/resources/vm/java/serviceImpl.java.vm new file mode 100644 index 0000000..461076b --- /dev/null +++ b/zzyl-generator/src/main/resources/vm/java/serviceImpl.java.vm @@ -0,0 +1,176 @@ +package ${packageName}.service.impl; + +import java.util.Arrays; +import java.util.List; +#foreach ($column in $columns) +#if($column.javaField == 'createTime' || $column.javaField == 'updateTime') +import com.zzyl.common.utils.DateUtils; +#break +#end +#end +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +#if($table.sub) +import java.util.ArrayList; +import com.zzyl.common.utils.StringUtils; +import org.springframework.transaction.annotation.Transactional; +import ${packageName}.domain.${subClassName}; +#end +import ${packageName}.mapper.${ClassName}Mapper; +import ${packageName}.domain.${ClassName}; +import ${packageName}.service.I${ClassName}Service; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; + +/** + * ${functionName}Service业务层处理 + * + * @author ${author} + * @date ${datetime} + */ +@Service +public class ${ClassName}ServiceImpl extends ServiceImpl<${ClassName}Mapper, ${ClassName}> implements I${ClassName}Service +{ + @Autowired + private ${ClassName}Mapper ${className}Mapper; + + /** + * 查询${functionName} + * + * @param ${pkColumn.javaField} ${functionName}主键 + * @return ${functionName} + */ + @Override + public ${ClassName} select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}) + { +## return ${className}Mapper.select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaField}); + return ${className}Mapper.selectById(${pkColumn.javaField}); + } + + /** + * 查询${functionName}列表 + * + * @param ${className} ${functionName} + * @return ${functionName} + */ + @Override + public List<${ClassName}> select${ClassName}List(${ClassName} ${className}) + { + return ${className}Mapper.select${ClassName}List(${className}); + } + + /** + * 新增${functionName} + * + * @param ${className} ${functionName} + * @return 结果 + */ +#if($table.sub) + @Transactional +#end + @Override + public int insert${ClassName}(${ClassName} ${className}) + { +###foreach ($column in $columns) +###if($column.javaField == 'createTime') +## ${className}.setCreateTime(DateUtils.getNowDate()); +###end +###end +#if($table.sub) + int rows = ${className}Mapper.insert${ClassName}(${className}); + insert${subClassName}(${className}); + return rows; +#else +## return ${className}Mapper.insert${ClassName}(${className}); + return ${className}Mapper.insert(${className}); +#end + } + + /** + * 修改${functionName} + * + * @param ${className} ${functionName} + * @return 结果 + */ +#if($table.sub) + @Transactional +#end + @Override + public int update${ClassName}(${ClassName} ${className}) + { +###foreach ($column in $columns) +###if($column.javaField == 'updateTime') +## ${className}.setUpdateTime(DateUtils.getNowDate()); +###end +###end +#if($table.sub) + ${className}Mapper.delete${subClassName}By${subTableFkClassName}(${className}.get${pkColumn.capJavaField}()); + insert${subClassName}(${className}); +#end +## return ${className}Mapper.update${ClassName}(${className}); + return ${className}Mapper.updateById(${className}); + } + + /** + * 批量删除${functionName} + * + * @param ${pkColumn.javaField}s 需要删除的${functionName}主键 + * @return 结果 + */ +#if($table.sub) + @Transactional +#end + @Override + public int delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaType}[] ${pkColumn.javaField}s) + { +#if($table.sub) + ${className}Mapper.delete${subClassName}By${subTableFkClassName}s(${pkColumn.javaField}s); +#end +## return ${className}Mapper.delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaField}s); + return ${className}Mapper.deleteBatchIds(Arrays.asList(${pkColumn.javaField}s)); + } + + /** + * 删除${functionName}信息 + * + * @param ${pkColumn.javaField} ${functionName}主键 + * @return 结果 + */ +#if($table.sub) + @Transactional +#end + @Override + public int delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}) + { +#if($table.sub) + ${className}Mapper.delete${subClassName}By${subTableFkClassName}(${pkColumn.javaField}); +#end +## return ${className}Mapper.delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaField}); + return ${className}Mapper.deleteById(${pkColumn.javaField}); + } +#if($table.sub) + + /** + * 新增${subTable.functionName}信息 + * + * @param ${className} ${functionName}对象 + */ + public void insert${subClassName}(${ClassName} ${className}) + { + List<${subClassName}> ${subclassName}List = ${className}.get${subClassName}List(); + ${pkColumn.javaType} ${pkColumn.javaField} = ${className}.get${pkColumn.capJavaField}(); + if (StringUtils.isNotNull(${subclassName}List)) + { + List<${subClassName}> list = new ArrayList<${subClassName}>(); + for (${subClassName} ${subclassName} : ${subclassName}List) + { + ${subclassName}.set${subTableFkClassName}(${pkColumn.javaField}); + list.add(${subclassName}); + } + if (list.size() > 0) + { + ${className}Mapper.batch${subClassName}(list); + } + } + } +#end +} diff --git a/zzyl-generator/src/main/resources/vm/java/sub-domain.java.vm b/zzyl-generator/src/main/resources/vm/java/sub-domain.java.vm new file mode 100644 index 0000000..9b592a1 --- /dev/null +++ b/zzyl-generator/src/main/resources/vm/java/sub-domain.java.vm @@ -0,0 +1,76 @@ +package ${packageName}.domain; + +#foreach ($import in $subImportList) +import ${import}; +#end +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.zzyl.common.annotation.Excel; +import com.zzyl.common.core.domain.BaseEntity; + +/** + * ${subTable.functionName}对象 ${subTableName} + * + * @author ${author} + * @date ${datetime} + */ +public class ${subClassName} extends BaseEntity +{ + private static final long serialVersionUID = 1L; + +#foreach ($column in $subTable.columns) +#if(!$table.isSuperColumn($column.javaField)) + /** $column.columnComment */ +#if($column.list) +#set($parentheseIndex=$column.columnComment.indexOf("(")) +#if($parentheseIndex != -1) +#set($comment=$column.columnComment.substring(0, $parentheseIndex)) +#else +#set($comment=$column.columnComment) +#end +#if($parentheseIndex != -1) + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") +#elseif($column.javaType == 'Date') + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "${comment}", width = 30, dateFormat = "yyyy-MM-dd") +#else + @Excel(name = "${comment}") +#end +#end + private $column.javaType $column.javaField; + +#end +#end +#foreach ($column in $subTable.columns) +#if(!$table.isSuperColumn($column.javaField)) +#if($column.javaField.length() > 2 && $column.javaField.substring(1,2).matches("[A-Z]")) +#set($AttrName=$column.javaField) +#else +#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) +#end + public void set${AttrName}($column.javaType $column.javaField) + { + this.$column.javaField = $column.javaField; + } + + public $column.javaType get${AttrName}() + { + return $column.javaField; + } +#end +#end + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) +#foreach ($column in $subTable.columns) +#if($column.javaField.length() > 2 && $column.javaField.substring(1,2).matches("[A-Z]")) +#set($AttrName=$column.javaField) +#else +#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) +#end + .append("${column.javaField}", get${AttrName}()) +#end + .toString(); + } +} diff --git a/zzyl-generator/src/main/resources/vm/js/api.js.vm b/zzyl-generator/src/main/resources/vm/js/api.js.vm new file mode 100644 index 0000000..9295524 --- /dev/null +++ b/zzyl-generator/src/main/resources/vm/js/api.js.vm @@ -0,0 +1,44 @@ +import request from '@/utils/request' + +// 查询${functionName}列表 +export function list${BusinessName}(query) { + return request({ + url: '/${moduleName}/${businessName}/list', + method: 'get', + params: query + }) +} + +// 查询${functionName}详细 +export function get${BusinessName}(${pkColumn.javaField}) { + return request({ + url: '/${moduleName}/${businessName}/' + ${pkColumn.javaField}, + method: 'get' + }) +} + +// 新增${functionName} +export function add${BusinessName}(data) { + return request({ + url: '/${moduleName}/${businessName}', + method: 'post', + data: data + }) +} + +// 修改${functionName} +export function update${BusinessName}(data) { + return request({ + url: '/${moduleName}/${businessName}', + method: 'put', + data: data + }) +} + +// 删除${functionName} +export function del${BusinessName}(${pkColumn.javaField}) { + return request({ + url: '/${moduleName}/${businessName}/' + ${pkColumn.javaField}, + method: 'delete' + }) +} diff --git a/zzyl-generator/src/main/resources/vm/sql/sql.vm b/zzyl-generator/src/main/resources/vm/sql/sql.vm new file mode 100644 index 0000000..0575583 --- /dev/null +++ b/zzyl-generator/src/main/resources/vm/sql/sql.vm @@ -0,0 +1,22 @@ +-- 菜单 SQL +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}', '${parentMenuId}', '1', '${businessName}', '${moduleName}/${businessName}/index', 1, 0, 'C', '0', '0', '${permissionPrefix}:list', '#', 'admin', sysdate(), '', null, '${functionName}菜单'); + +-- 按钮父菜单ID +SELECT @parentId := LAST_INSERT_ID(); + +-- 按钮 SQL +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}查询', @parentId, '1', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:query', '#', 'admin', sysdate(), '', null, ''); + +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}新增', @parentId, '2', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:add', '#', 'admin', sysdate(), '', null, ''); + +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}修改', @parentId, '3', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:edit', '#', 'admin', sysdate(), '', null, ''); + +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}删除', @parentId, '4', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:remove', '#', 'admin', sysdate(), '', null, ''); + +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}导出', @parentId, '5', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:export', '#', 'admin', sysdate(), '', null, ''); \ No newline at end of file diff --git a/zzyl-generator/src/main/resources/vm/vue/index-tree.vue.vm b/zzyl-generator/src/main/resources/vm/vue/index-tree.vue.vm new file mode 100644 index 0000000..4819c2a --- /dev/null +++ b/zzyl-generator/src/main/resources/vm/vue/index-tree.vue.vm @@ -0,0 +1,505 @@ + + + diff --git a/zzyl-generator/src/main/resources/vm/vue/index.vue.vm b/zzyl-generator/src/main/resources/vm/vue/index.vue.vm new file mode 100644 index 0000000..6296014 --- /dev/null +++ b/zzyl-generator/src/main/resources/vm/vue/index.vue.vm @@ -0,0 +1,602 @@ + + + diff --git a/zzyl-generator/src/main/resources/vm/vue/v3/index-tree.vue.vm b/zzyl-generator/src/main/resources/vm/vue/v3/index-tree.vue.vm new file mode 100644 index 0000000..c54d62b --- /dev/null +++ b/zzyl-generator/src/main/resources/vm/vue/v3/index-tree.vue.vm @@ -0,0 +1,474 @@ + + + diff --git a/zzyl-generator/src/main/resources/vm/vue/v3/index.vue.vm b/zzyl-generator/src/main/resources/vm/vue/v3/index.vue.vm new file mode 100644 index 0000000..8b25665 --- /dev/null +++ b/zzyl-generator/src/main/resources/vm/vue/v3/index.vue.vm @@ -0,0 +1,590 @@ + + + diff --git a/zzyl-generator/src/main/resources/vm/xml/mapper.xml.vm b/zzyl-generator/src/main/resources/vm/xml/mapper.xml.vm new file mode 100644 index 0000000..456755b --- /dev/null +++ b/zzyl-generator/src/main/resources/vm/xml/mapper.xml.vm @@ -0,0 +1,140 @@ + + + + + +#foreach ($column in $columns) + +#end + +#if($table.sub) + + + + + + +#foreach ($column in $subTable.columns) + +#end + +#end + + + select#foreach($column in $columns) $column.columnName#if($foreach.count != $columns.size()),#end#end from ${tableName} + + + + + +#if($table.sub) + + +#end + + + insert into ${tableName} + +#foreach($column in $columns) +#if($column.columnName != $pkColumn.columnName || !$pkColumn.increment) + $column.columnName, +#end +#end + + +#foreach($column in $columns) +#if($column.columnName != $pkColumn.columnName || !$pkColumn.increment) + #{$column.javaField}, +#end +#end + + + + + update ${tableName} + +#foreach($column in $columns) +#if($column.columnName != $pkColumn.columnName) + $column.columnName = #{$column.javaField}, +#end +#end + + where ${pkColumn.columnName} = #{${pkColumn.javaField}} + + + + delete from ${tableName} where ${pkColumn.columnName} = #{${pkColumn.javaField}} + + + + delete from ${tableName} where ${pkColumn.columnName} in + + #{${pkColumn.javaField}} + + +#if($table.sub) + + + delete from ${subTableName} where ${subTableFkName} in + + #{${subTableFkclassName}} + + + + + delete from ${subTableName} where ${subTableFkName} = #{${subTableFkclassName}} + + + + insert into ${subTableName}(#foreach($column in $subTable.columns) $column.columnName#if($foreach.count != $subTable.columns.size()),#end#end) values + + (#foreach($column in $subTable.columns) #{item.$column.javaField}#if($foreach.count != $subTable.columns.size()),#end#end) + + +#end + \ No newline at end of file diff --git a/zzyl-generator/src/main/resources/vms/index.html.vm b/zzyl-generator/src/main/resources/vms/index.html.vm new file mode 100644 index 0000000..4dfd60e --- /dev/null +++ b/zzyl-generator/src/main/resources/vms/index.html.vm @@ -0,0 +1,13 @@ + + + + + + velocity快速入门 + + + +

心怀梦想,坚持不懈,成功即在前方。${message}

+ + + \ No newline at end of file diff --git a/zzyl-generator/src/test/java/com/itheima/velocity/VelocityTest.java b/zzyl-generator/src/test/java/com/itheima/velocity/VelocityTest.java new file mode 100644 index 0000000..6f1359b --- /dev/null +++ b/zzyl-generator/src/test/java/com/itheima/velocity/VelocityTest.java @@ -0,0 +1,31 @@ +package com.itheima.velocity; + +import com.zzyl.generator.util.VelocityInitializer; +import org.apache.velocity.Template; +import org.apache.velocity.VelocityContext; +import org.apache.velocity.app.Velocity; + +import java.io.FileWriter; +import java.io.IOException; + +public class VelocityTest { + public static void main(String[] args) throws IOException { + // 1.初始化模板引擎 + VelocityInitializer.initVelocity(); + + // 2.创建Velocity上下文对象 + VelocityContext context = new VelocityContext(); + // 准备数据模型 + context.put("message", "加油小朋友"); + + // 3.获取模板 + Template template = Velocity.getTemplate("vms/index.html.vm", "UTF-8"); + + // 4.合并模板和数据模型 + FileWriter fw = new FileWriter("zzyl-generator\\src\\main\\resources\\index.html"); + template.merge(context, fw); + + // 5.关闭流 + fw.close(); + } +} diff --git a/zzyl-nursing-platform/pom.xml b/zzyl-nursing-platform/pom.xml new file mode 100644 index 0000000..e620d36 --- /dev/null +++ b/zzyl-nursing-platform/pom.xml @@ -0,0 +1,46 @@ + + + 4.0.0 + + com.zzyl + zzyl + 3.8.8 + + + zzyl-nursing-platform + + + 11 + 11 + UTF-8 + + + + + com.zzyl + zzyl-framework + + + + com.zzyl + zzyl-oss + + + + + org.apache.qpid + qpid-jms-client + 0.61.0 + + + + + org.springframework.boot + spring-boot-starter-websocket + + + + + \ No newline at end of file diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/config/WebSocketConfig.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/config/WebSocketConfig.java new file mode 100644 index 0000000..9c070e6 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/config/WebSocketConfig.java @@ -0,0 +1,25 @@ +package com.zzyl.nursing.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +/** + * WebSocket配置 + * + * @author Zhy + * @version 1.0 + * @date 2025-03-12 12:00 + */ +@Configuration +public class WebSocketConfig { + + /** + * 注册基于 @ServerEndpoint 声明的 Websocket Endpoint + */ + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/config/WebSocketServer.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/config/WebSocketServer.java new file mode 100644 index 0000000..398159b --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/config/WebSocketServer.java @@ -0,0 +1,134 @@ +package com.zzyl.nursing.config; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSONUtil; +import com.zzyl.common.exception.base.BaseException; +import com.zzyl.nursing.vo.AlertNotifyVo; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; +import org.springframework.web.socket.config.annotation.EnableWebSocket; + +import javax.websocket.*; +import javax.websocket.server.PathParam; +import javax.websocket.server.ServerEndpoint; +import java.io.IOException; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +/** + * WebSocket服务端 + * + * @author Zhy + * @version 1.0 + * @date 2025-03-12 12:00 + */ +@Slf4j +@Component +@EnableWebSocket +@ServerEndpoint("/ws/{sid}") +public class WebSocketServer { + + private static Map sessionMap = new HashMap<>(); + + /** + * 连接建立时触发 + * + * @param session 会话 + * @param sid 用户id + */ + @OnOpen + public void onOpen(Session session, @PathParam("sid") String sid) { + log.info("有客户端连接到了服务器 , {}", sid); + sessionMap.put(sid, session); + } + + /** + * 服务端接收到消息时触发 + * + * @param session 会话 + * @param message 消息 + * @param sid 用户id + */ + @OnMessage + public void onMessage(Session session, String message, @PathParam("sid") String sid) { + log.info("接收到了客户端 {} 发来的消息 : {}", sid, message); + } + + /** + * 连接关闭时触发 + * + * @param session 会话 + * @param sid 用户id + */ + @OnClose + public void onClose(Session session, @PathParam("sid") String sid) { + System.out.println("连接断开:" + sid); + sessionMap.remove(sid); + } + + /** + * 通信发生错误时触发 + * + * @param session 会话 + * @param sid 用户id + * @param throwable 异常 + */ + @OnError + public void onError(Session session, @PathParam("sid") String sid, Throwable throwable) { + System.out.println("出现错误:" + sid); + throwable.printStackTrace(); + } + + /** + * 广播消息 + * + * @param message 消息 + */ + public void sendMessageToAll(String message) throws IOException { + Collection sessions = sessionMap.values(); + if (!CollectionUtils.isEmpty(sessions)) { + for (Session session : sessions) { + // 服务器向客户端发送消息 + session.getBasicRemote().sendText(message); + } + } + } + + /** + * 发送websocket消息给指定消费者 + * + * @param alertNotifyVo 报警消息 + * @param userIds 报警数据map + */ + public void sendMessageToConsumer(AlertNotifyVo alertNotifyVo, Collection userIds) { + // 如果消费者为空,程序结束 + if (CollUtil.isEmpty(userIds)) { + return; + } + + // 如果 Websocket 客户端为空,程序结束 + if (ObjectUtil.isEmpty(sessionMap)) { + return; + } + + // 遍历消费者,发送消息 + // key为消息接收人id,value为报警数据id + userIds.forEach(userId -> { + // 获取该消费者的websocket连接,如果不存在,跳出本次循环 + Session session = sessionMap.get(String.valueOf(userId)); + if (ObjectUtil.isEmpty(session)) { + return; + } + // 获取该消费者的websocket连接,并发送消息 + try { + session.getBasicRemote().sendText(JSONUtil.toJsonStr(alertNotifyVo)); + } catch (IOException e) { + throw new BaseException("websocket推送消息失败"); + } + }); + } + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/AlertDataController.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/AlertDataController.java new file mode 100644 index 0000000..c76ecd2 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/AlertDataController.java @@ -0,0 +1,128 @@ +package com.zzyl.nursing.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; + +import com.zzyl.common.core.domain.R; +import com.zzyl.nursing.dto.AlertDataPageQueryDto; +import com.zzyl.nursing.dto.HandleAlertDataDto; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import lombok.RequiredArgsConstructor; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.zzyl.common.annotation.Log; +import com.zzyl.common.core.controller.BaseController; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.enums.BusinessType; +import com.zzyl.nursing.domain.AlertData; +import com.zzyl.nursing.service.IAlertDataService; +import com.zzyl.common.utils.poi.ExcelUtil; +import com.zzyl.common.core.page.TableDataInfo; + +/** + * 报警数据Controller + * + * @author Zhy + * @date 2025-03-11 + */ +@Api(tags = "报警数据管理") +@RestController +@RequestMapping("/nursing/alertData") +@RequiredArgsConstructor +public class AlertDataController extends BaseController { + + private final IAlertDataService alertDataService; + + /** + * 查询报警数据列表 + */ + @ApiOperation("查询报警数据列表") + @PreAuthorize("@ss.hasPermi('nursing:alertData:list')") + @GetMapping("/list") + public TableDataInfo> pageQueryAlertData( + @ApiParam("报警数据查询条件") AlertDataPageQueryDto alertDataPageQueryDto + ) { + startPage(); + List list = alertDataService.pageQueryAlertData(alertDataPageQueryDto); + return getDataTable(list); + } + + /** + * 导出报警数据列表 + */ + @ApiOperation("导出报警数据列表") + @PreAuthorize("@ss.hasPermi('nursing:alertData:export')") + @Log(title = "报警数据", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(@ApiParam(value = "报警数据查询条件") HttpServletResponse response, AlertData alertData) { + List list = alertDataService.selectAlertDataList(alertData); + ExcelUtil util = new ExcelUtil(AlertData.class); + util.exportExcel(response, list, "报警数据数据"); + } + + /** + * 获取报警数据详细信息 + */ + @ApiOperation("获取报警数据详细信息") + @PreAuthorize("@ss.hasPermi('nursing:alertData:query')") + @GetMapping(value = "/{id}") + public R getInfo(@ApiParam("报警数据ID") @PathVariable("id") Long id) { + return R.ok(alertDataService.selectAlertDataById(id)); + } + + /** + * 新增报警数据 + */ + @ApiOperation("新增报警数据") + @PreAuthorize("@ss.hasPermi('nursing:alertData:add')") + @Log(title = "报警数据", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@ApiParam("报警数据信息") @RequestBody AlertData alertData) { + return toAjax(alertDataService.insertAlertData(alertData)); + } + + /** + * 修改报警数据 + */ + @ApiOperation("修改报警数据") + @PreAuthorize("@ss.hasPermi('nursing:alertData:edit')") + @Log(title = "报警数据", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@ApiParam("报警数据信息") @RequestBody AlertData alertData) { + return toAjax(alertDataService.updateAlertData(alertData)); + } + + /** + * 删除报警数据 + */ + @ApiOperation("删除报警数据") + @PreAuthorize("@ss.hasPermi('nursing:alertData:remove')") + @Log(title = "报警数据", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@ApiParam("报警数据ID数组") @PathVariable Long[] ids) { + return toAjax(alertDataService.deleteAlertDataByIds(ids)); + } + + /** + * 处理设备报警数据 + * + * @return: + * @param: + */ + @ApiOperation("处理设备报警数据") + @PutMapping("/handleAlertData") + public AjaxResult handleAlertData(@ApiParam("报警数据信息") @RequestBody HandleAlertDataDto handleAlertDataDto) { + alertDataService.handleAlertData(handleAlertDataDto); + return success(); + } + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/AlertRuleController.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/AlertRuleController.java new file mode 100644 index 0000000..fb6516c --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/AlertRuleController.java @@ -0,0 +1,111 @@ +package com.zzyl.nursing.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; + +import com.zzyl.common.core.domain.R; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import lombok.RequiredArgsConstructor; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.zzyl.common.annotation.Log; +import com.zzyl.common.core.controller.BaseController; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.enums.BusinessType; +import com.zzyl.nursing.domain.AlertRule; +import com.zzyl.nursing.service.IAlertRuleService; +import com.zzyl.common.utils.poi.ExcelUtil; +import com.zzyl.common.core.page.TableDataInfo; + +/** + * 报警规则Controller + * + * @author Zhy + * @date 2025-03-11 + */ +@Api(tags = "报警规则管理") +@RestController +@RequestMapping("/nursing/alertRule") +@RequiredArgsConstructor +public class AlertRuleController extends BaseController { + + private final IAlertRuleService alertRuleService; + + /** + * 查询报警规则列表 + */ + @ApiOperation("查询报警规则列表") + @PreAuthorize("@ss.hasPermi('nursing:AlertRule:list')") + @GetMapping("/list") + public TableDataInfo> list(@ApiParam("报警规则查询条件") AlertRule alertRule) { + startPage(); + List list = alertRuleService.selectAlertRuleList(alertRule); + return getDataTable(list); + } + + /** + * 导出报警规则列表 + */ + @ApiOperation("导出报警规则列表") + @PreAuthorize("@ss.hasPermi('nursing:AlertRule:export')") + @Log(title = "报警规则", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(@ApiParam(value = "报警规则查询条件") HttpServletResponse response, AlertRule alertRule) { + List list = alertRuleService.selectAlertRuleList(alertRule); + ExcelUtil util = new ExcelUtil(AlertRule.class); + util.exportExcel(response, list, "报警规则数据"); + } + + /** + * 获取报警规则详细信息 + */ + @ApiOperation("获取报警规则详细信息") + @PreAuthorize("@ss.hasPermi('nursing:AlertRule:query')") + @GetMapping(value = "/{id}") + public R getInfo(@ApiParam("报警规则ID") @PathVariable("id") Long id) { + return R.ok(alertRuleService.selectAlertRuleById(id)); + } + + /** + * 修改报警规则 + */ + @ApiOperation("修改报警规则") + @PreAuthorize("@ss.hasPermi('nursing:AlertRule:edit')") + @Log(title = "报警规则", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@ApiParam("报警规则信息") @RequestBody AlertRule alertRule) { + return toAjax(alertRuleService.updateAlertRule(alertRule)); + } + + /** + * 删除报警规则 + */ + @ApiOperation("删除报警规则") + @PreAuthorize("@ss.hasPermi('nursing:AlertRule:remove')") + @Log(title = "报警规则", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@ApiParam("报警规则ID数组") @PathVariable Long[] ids) { + return toAjax(alertRuleService.deleteAlertRuleByIds(ids)); + } + + /** + * 新增报警规则 + */ + @ApiOperation("新增报警规则") + @PreAuthorize("@ss.hasPermi('nursing:AlertRule:add')") + @Log(title = "报警规则", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@ApiParam("报警规则信息") @RequestBody AlertRule alertRule) { + return toAjax(alertRuleService.insertAlertRule(alertRule)); + } + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/BedController.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/BedController.java new file mode 100644 index 0000000..629f03e --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/BedController.java @@ -0,0 +1,93 @@ +package com.zzyl.nursing.controller; + +import com.zzyl.common.annotation.Log; +import com.zzyl.common.core.controller.BaseController; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.core.domain.R; +import com.zzyl.common.core.page.TableDataInfo; +import com.zzyl.common.enums.BusinessType; +import com.zzyl.nursing.domain.Bed; +import com.zzyl.nursing.service.IBedService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 床位Controller + * + * @author ruoyi + * @date 2024-04-26 + */ +@RestController +@RequestMapping("/elder/bed") +@Api(tags = "床位相关接口") +public class BedController extends BaseController +{ + @Autowired + private IBedService bedService; + + /** + * 查询床位列表 + */ + @PreAuthorize("@ss.hasPermi('elder:bed:list')") + @GetMapping("/list") + @ApiOperation("查询床位列表") + public TableDataInfo list(Bed bed) + { + startPage(); + List list = bedService.selectBedList(bed); + return getDataTable(list); + } + + /** + * 获取床位详细信息 + */ + @PreAuthorize("@ss.hasPermi('elder:bed:query')") + @GetMapping(value = "/{id}") + @ApiOperation("获取床位详细信息") + public R getInfo(@ApiParam(value = "床位ID", required = true) @PathVariable("id") Long id) + { + return R.ok(bedService.selectBedById(id)); + } + + /** + * 新增床位 + */ + @PreAuthorize("@ss.hasPermi('elder:bed:add')") + @Log(title = "床位", businessType = BusinessType.INSERT) + @PostMapping + @ApiOperation("新增床位") + public AjaxResult add(@RequestBody Bed bed) + { + return toAjax(bedService.insertBed(bed)); + } + + /** + * 修改床位 + */ + @ApiOperation("修改床位") + @PreAuthorize("@ss.hasPermi('elder:bed:edit')") + @Log(title = "床位", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody Bed bed) + { + return toAjax(bedService.updateBed(bed)); + } + + /** + * 删除床位 + */ + @ApiOperation("删除床位") + @PreAuthorize("@ss.hasPermi('elder:bed:remove')") + @Log(title = "床位", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@ApiParam(value = "床位ID", required = true) @PathVariable Long[] ids) + { + return toAjax(bedService.deleteBedByIds(ids)); + } +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/CheckInConfigController.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/CheckInConfigController.java new file mode 100644 index 0000000..e08f989 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/CheckInConfigController.java @@ -0,0 +1,117 @@ +package com.zzyl.nursing.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; + +import com.zzyl.common.core.domain.R; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import lombok.RequiredArgsConstructor; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.zzyl.common.annotation.Log; +import com.zzyl.common.core.controller.BaseController; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.enums.BusinessType; +import com.zzyl.nursing.domain.CheckInConfig; +import com.zzyl.nursing.service.ICheckInConfigService; +import com.zzyl.common.utils.poi.ExcelUtil; +import com.zzyl.common.core.page.TableDataInfo; + +/** + * 入住配置表Controller + * + * @Author: Zhy + * @Date: 2025-02-25 + */ +@Api(tags = "入住配置表管理") +@RestController +@RequestMapping("/nursing/checkInConfig") +@RequiredArgsConstructor +public class CheckInConfigController extends BaseController +{ + + private final ICheckInConfigService checkInConfigService; + + /** + * 查询入住配置表列表 + */ + @ApiOperation("查询入住配置表列表") + @PreAuthorize("@ss.hasPermi('nursing:checkInConfig:list')") + @GetMapping("/list") + public TableDataInfo> list(@ApiParam("入住配置表查询条件") CheckInConfig checkInConfig) + { + startPage(); + List list = checkInConfigService.selectCheckInConfigList(checkInConfig); + return getDataTable(list); + } + + /** + * 导出入住配置表列表 + */ + @ApiOperation("导出入住配置表列表") + @PreAuthorize("@ss.hasPermi('nursing:checkInConfig:export')") + @Log(title = "入住配置表", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(@ApiParam(value = "入住配置表查询条件") HttpServletResponse response, CheckInConfig checkInConfig) + { + List list = checkInConfigService.selectCheckInConfigList(checkInConfig); + ExcelUtil util = new ExcelUtil<>(CheckInConfig.class); + util.exportExcel(response, list, "入住配置表数据"); + } + + /** + * 获取入住配置表详细信息 + */ + @ApiOperation("获取入住配置表详细信息") + @PreAuthorize("@ss.hasPermi('nursing:checkInConfig:query')") + @GetMapping(value = "/{id}") + public R getInfo(@ApiParam("入住配置表ID") @PathVariable("id") Long id) + { + return R.ok(checkInConfigService.selectCheckInConfigById(id)); + } + + /** + * 新增入住配置表 + */ + @ApiOperation("新增入住配置表") + @PreAuthorize("@ss.hasPermi('nursing:checkInConfig:add')") + @Log(title = "入住配置表", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@ApiParam("入住配置表信息") @RequestBody CheckInConfig checkInConfig) + { + return toAjax(checkInConfigService.insertCheckInConfig(checkInConfig)); + } + + /** + * 修改入住配置表 + */ + @ApiOperation("修改入住配置表") + @PreAuthorize("@ss.hasPermi('nursing:checkInConfig:edit')") + @Log(title = "入住配置表", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@ApiParam("入住配置表信息") @RequestBody CheckInConfig checkInConfig) + { + return toAjax(checkInConfigService.updateCheckInConfig(checkInConfig)); + } + + /** + * 删除入住配置表 + */ + @ApiOperation("删除入住配置表") + @PreAuthorize("@ss.hasPermi('nursing:checkInConfig:remove')") + @Log(title = "入住配置表", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@ApiParam("入住配置表ID数组") @PathVariable Long[] ids) + { + return toAjax(checkInConfigService.deleteCheckInConfigByIds(ids)); + } +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/CheckInController.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/CheckInController.java new file mode 100644 index 0000000..ed0ea20 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/CheckInController.java @@ -0,0 +1,133 @@ +package com.zzyl.nursing.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; + +import com.zzyl.common.core.domain.R; +import com.zzyl.nursing.dto.CheckInApplyDto; +import com.zzyl.nursing.vo.CheckInDetailVo; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import lombok.RequiredArgsConstructor; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.zzyl.common.annotation.Log; +import com.zzyl.common.core.controller.BaseController; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.enums.BusinessType; +import com.zzyl.nursing.domain.CheckIn; +import com.zzyl.nursing.service.ICheckInService; +import com.zzyl.common.utils.poi.ExcelUtil; +import com.zzyl.common.core.page.TableDataInfo; + +/** + * 入住表Controller + * + * @Author: Zhy + * @Date: 2025-02-25 + */ +@Api(tags = "入住表管理") +@RestController +@RequestMapping("/nursing/checkIn") +@RequiredArgsConstructor +public class CheckInController extends BaseController { + + private final ICheckInService checkInService; + + /** + * 查询入住表列表 + */ + @ApiOperation("查询入住表列表") + @PreAuthorize("@ss.hasPermi('nursing:checkIn:list')") + @GetMapping("/list") + public TableDataInfo> list(@ApiParam("入住表查询条件") CheckIn checkIn) { + startPage(); + List list = checkInService.selectCheckInList(checkIn); + return getDataTable(list); + } + + /** + * 导出入住表列表 + */ + @ApiOperation("导出入住表列表") + @PreAuthorize("@ss.hasPermi('nursing:checkIn:export')") + @Log(title = "入住表", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(@ApiParam(value = "入住表查询条件") HttpServletResponse response, CheckIn checkIn) { + List list = checkInService.selectCheckInList(checkIn); + ExcelUtil util = new ExcelUtil<>(CheckIn.class); + util.exportExcel(response, list, "入住表数据"); + } + + /** + * 获取入住表详细信息 + */ + @ApiOperation("获取入住表详细信息") + @PreAuthorize("@ss.hasPermi('nursing:checkIn:query')") + @GetMapping(value = "/{id}") + public R getInfo(@ApiParam("入住表ID") @PathVariable("id") Long id) { + return R.ok(checkInService.selectCheckInById(id)); + } + + /** + * 新增入住表 + */ + @ApiOperation("新增入住表") + @PreAuthorize("@ss.hasPermi('nursing:checkIn:add')") + @Log(title = "入住表", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@ApiParam("入住表信息") @RequestBody CheckIn checkIn) { + return toAjax(checkInService.insertCheckIn(checkIn)); + } + + /** + * 修改入住表 + */ + @ApiOperation("修改入住表") + @PreAuthorize("@ss.hasPermi('nursing:checkIn:edit')") + @Log(title = "入住表", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@ApiParam("入住表信息") @RequestBody CheckIn checkIn) { + return toAjax(checkInService.updateCheckIn(checkIn)); + } + + /** + * 删除入住表 + */ + @ApiOperation("删除入住表") + @PreAuthorize("@ss.hasPermi('nursing:checkIn:remove')") + @Log(title = "入住表", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@ApiParam("入住表ID数组") @PathVariable Long[] ids) { + return toAjax(checkInService.deleteCheckInByIds(ids)); + } + + /** + * 申请入住 + */ + @ApiOperation("申请入住") + @Log(title = "入住表", businessType = BusinessType.INSERT) + @PostMapping("/apply") + public AjaxResult apply(@ApiParam("申请入住请求DTO") @RequestBody CheckInApplyDto checkInApplyDto) { + checkInService.apply(checkInApplyDto); + return AjaxResult.success("操作成功"); + } + + /** + * 获取老人入住详细信息 + */ + @ApiOperation("获取老人入住详细信息") + @GetMapping(value = "/detail/{id}") + public R getCheckInInfo(@ApiParam("入住记录ID") @PathVariable("id") Long id) { + return R.ok(checkInService.getCheckInInfo(id)); + } + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/ContractController.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/ContractController.java new file mode 100644 index 0000000..3a68726 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/ContractController.java @@ -0,0 +1,110 @@ +package com.zzyl.nursing.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; + +import com.zzyl.common.core.domain.R; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import lombok.RequiredArgsConstructor; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.zzyl.common.annotation.Log; +import com.zzyl.common.core.controller.BaseController; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.enums.BusinessType; +import com.zzyl.nursing.domain.Contract; +import com.zzyl.nursing.service.IContractService; +import com.zzyl.common.utils.poi.ExcelUtil; +import com.zzyl.common.core.page.TableDataInfo; + +/** + * 合同表Controller + * + * @Author: Zhy + * @Date: 2025-02-25 + */ +@Api(tags = "合同表管理") +@RestController +@RequestMapping("/nursing/contract") +@RequiredArgsConstructor +public class ContractController extends BaseController { + + private final IContractService contractService; + + /** + * 查询合同表列表 + */ + @ApiOperation("查询合同表列表") + @PreAuthorize("@ss.hasPermi('nursing:contract:list')") + @GetMapping("/list") + public TableDataInfo> list(@ApiParam("合同表查询条件") Contract contract) { + startPage(); + List list = contractService.selectContractList(contract); + return getDataTable(list); + } + + /** + * 导出合同表列表 + */ + @ApiOperation("导出合同表列表") + @PreAuthorize("@ss.hasPermi('nursing:contract:export')") + @Log(title = "合同表", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(@ApiParam(value = "合同表查询条件") HttpServletResponse response, Contract contract) { + List list = contractService.selectContractList(contract); + ExcelUtil util = new ExcelUtil<>(Contract.class); + util.exportExcel(response, list, "合同表数据"); + } + + /** + * 获取合同表详细信息 + */ + @ApiOperation("获取合同表详细信息") + @PreAuthorize("@ss.hasPermi('nursing:contract:query')") + @GetMapping(value = "/{id}") + public R getInfo(@ApiParam("合同表ID") @PathVariable("id") Integer id) { + return R.ok(contractService.selectContractById(id)); + } + + /** + * 新增合同表 + */ + @ApiOperation("新增合同表") + @PreAuthorize("@ss.hasPermi('nursing:contract:add')") + @Log(title = "合同表", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@ApiParam("合同表信息") @RequestBody Contract contract) { + return toAjax(contractService.insertContract(contract)); + } + + /** + * 修改合同表 + */ + @ApiOperation("修改合同表") + @PreAuthorize("@ss.hasPermi('nursing:contract:edit')") + @Log(title = "合同表", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@ApiParam("合同表信息") @RequestBody Contract contract) { + return toAjax(contractService.updateContract(contract)); + } + + /** + * 删除合同表 + */ + @ApiOperation("删除合同表") + @PreAuthorize("@ss.hasPermi('nursing:contract:remove')") + @Log(title = "合同表", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@ApiParam("合同表ID数组") @PathVariable Integer[] ids) { + return toAjax(contractService.deleteContractByIds(ids)); + } +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/DeviceController.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/DeviceController.java new file mode 100644 index 0000000..e6753dc --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/DeviceController.java @@ -0,0 +1,171 @@ +package com.zzyl.nursing.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; + +import com.huaweicloud.sdk.iotda.v5.model.ServiceCapability; +import com.zzyl.common.core.domain.R; +import com.zzyl.nursing.dto.DeviceDto; +import com.zzyl.nursing.vo.DeviceDetailVo; +import com.zzyl.nursing.vo.DeviceReportDataVo; +import com.zzyl.nursing.vo.ProductVo; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import lombok.RequiredArgsConstructor; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; +import com.zzyl.common.annotation.Log; +import com.zzyl.common.core.controller.BaseController; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.enums.BusinessType; +import com.zzyl.nursing.domain.Device; +import com.zzyl.nursing.service.IDeviceService; +import com.zzyl.common.utils.poi.ExcelUtil; +import com.zzyl.common.core.page.TableDataInfo; + +/** + * 设备Controller + * + * @author Zhy + * @date 2025-03-06 + */ +@Api(tags = "设备管理") +@RestController +@RequestMapping("/nursing/device") +@RequiredArgsConstructor +public class DeviceController extends BaseController { + + private final IDeviceService deviceService; + + /** + * 查询设备列表 + */ + @ApiOperation("查询设备列表") + @PreAuthorize("@ss.hasPermi('nursing:device:list')") + @GetMapping("/list") + public TableDataInfo> list(@ApiParam("设备查询条件") Device device) { + startPage(); + List list = deviceService.selectDeviceList(device); + return getDataTable(list); + } + + /** + * 导出设备列表 + */ + @ApiOperation("导出设备列表") + @PreAuthorize("@ss.hasPermi('nursing:device:export')") + @Log(title = "设备", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(@ApiParam(value = "设备查询条件") HttpServletResponse response, Device device) { + List list = deviceService.selectDeviceList(device); + ExcelUtil util = new ExcelUtil(Device.class); + util.exportExcel(response, list, "设备数据"); + } + + /** + * 从物联网平台同步产品列表 + * + * @return: + * @param: + */ + @ApiOperation("从物联网平台同步产品列表") + @PostMapping("/syncProductList") + public AjaxResult syncProductList() { + deviceService.syncProductList(); + return AjaxResult.success(); + } + + /** + * 查询所有产品列表 + * + * @return: + * @param: + */ + @ApiOperation("查询所有产品列表") + @GetMapping(value = "/allProduct") + public R> allProduct() { + return R.ok(deviceService.allProduct()); + } + + /** + * 注册设备 + * + * @return: + * @param: + */ + @ApiOperation("注册设备") + @PostMapping("/register") + public AjaxResult registerProduct(@ApiParam("设备信息") @RequestBody DeviceDto deviceDto) { + deviceService.registerProduct(deviceDto); + return AjaxResult.success(); + } + + /** + * 查询设备详细数据 + * + * @return: + * @param: + */ + @ApiOperation("查询设备详细数据") + @GetMapping("/{iotId}") + public R getProductByIotId(@ApiParam("设备标识码") @PathVariable("iotId") String iotId) { + return R.ok(deviceService.queryDeviceDetail(iotId)); + } + + /** + * 查询设备上报数据 + * + * @return: + * @param: + */ + @ApiOperation("查询设备详细数据") + @GetMapping("/queryServiceProperties/{iotId}") + public R> queryDeviceReportData( + @ApiParam("设备标识码") @PathVariable("iotId") String iotId + ) { + return R.ok(deviceService.queryDeviceReportData(iotId)); + } + + /** + * 修改设备 + * + * @return: + * @param: + */ + @ApiOperation("修改设备") + @PutMapping + public AjaxResult updateDevice(@ApiParam("设备数据") @RequestBody Device device) { + deviceService.updateDevice(device); + return success(); + } + + /** + * 删除设备 + * + * @return: + * @param: + */ + @ApiOperation("修改设备") + @DeleteMapping("/{iotId}") + public AjaxResult deleteDevice(@ApiParam("设备标识码") @PathVariable("iotId") String iotId) { + deviceService.deleteDeviceByIotId(iotId); + return success(); + } + + /** + * 获取产品对应的服务信息 + * + * @return: + * @param: + */ + @ApiOperation("获取产品对应的服务信息") + @GetMapping("/queryProduct/{productKey}") + public R> queryProductByProductKey( + @ApiParam("产品key") @PathVariable("productKey") String productKey + ) { + List list = deviceService.queryProductByProductKey(productKey); + return R.ok(list); + } + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/DeviceDataController.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/DeviceDataController.java new file mode 100644 index 0000000..f2d8bc5 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/DeviceDataController.java @@ -0,0 +1,109 @@ +package com.zzyl.nursing.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; + +import com.zzyl.common.core.domain.R; +import com.zzyl.nursing.dto.DeviceDataPageReqDto; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import lombok.RequiredArgsConstructor; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.zzyl.common.annotation.Log; +import com.zzyl.common.core.controller.BaseController; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.enums.BusinessType; +import com.zzyl.nursing.domain.DeviceData; +import com.zzyl.nursing.service.IDeviceDataService; +import com.zzyl.common.utils.poi.ExcelUtil; +import com.zzyl.common.core.page.TableDataInfo; + +/** + * 设备数据Controller + * + * @author Zhy + * @date 2025-03-08 + */ +@Api(tags = "设备数据管理") +@RestController +@RequestMapping("/nursing/data") +@RequiredArgsConstructor +public class DeviceDataController extends BaseController { + + private final IDeviceDataService deviceDataService; + + /** + * 查询设备数据列表 + */ + @ApiOperation("查询设备数据列表") + @PreAuthorize("@ss.hasPermi('nursing:data:list')") + @GetMapping("/list") + public TableDataInfo list(@ApiParam("设备数据查询条件") DeviceDataPageReqDto deviceDataPageReqDto) { + return deviceDataService.selectDeviceDataPageList(deviceDataPageReqDto); + } + + /** + * 导出设备数据列表 + */ + @ApiOperation("导出设备数据列表") + @PreAuthorize("@ss.hasPermi('nursing:data:export')") + @Log(title = "设备数据", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(@ApiParam(value = "设备数据查询条件") HttpServletResponse response, DeviceData deviceData) { + List list = deviceDataService.selectDeviceDataList(deviceData); + ExcelUtil util = new ExcelUtil<>(DeviceData.class); + util.exportExcel(response, list, "设备数据数据"); + } + + /** + * 获取设备数据详细信息 + */ + @ApiOperation("获取设备数据详细信息") + @PreAuthorize("@ss.hasPermi('nursing:data:query')") + @GetMapping(value = "/{id}") + public R getInfo(@ApiParam("设备数据ID") @PathVariable("id") Long id) { + return R.ok(deviceDataService.selectDeviceDataById(id)); + } + + /** + * 新增设备数据 + */ + @ApiOperation("新增设备数据") + @PreAuthorize("@ss.hasPermi('nursing:data:add')") + @Log(title = "设备数据", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@ApiParam("设备数据信息") @RequestBody DeviceData deviceData) { + return toAjax(deviceDataService.insertDeviceData(deviceData)); + } + + /** + * 修改设备数据 + */ + @ApiOperation("修改设备数据") + @PreAuthorize("@ss.hasPermi('nursing:data:edit')") + @Log(title = "设备数据", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@ApiParam("设备数据信息") @RequestBody DeviceData deviceData) { + return toAjax(deviceDataService.updateDeviceData(deviceData)); + } + + /** + * 删除设备数据 + */ + @ApiOperation("删除设备数据") + @PreAuthorize("@ss.hasPermi('nursing:data:remove')") + @Log(title = "设备数据", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@ApiParam("设备数据ID数组") @PathVariable Long[] ids) { + return toAjax(deviceDataService.deleteDeviceDataByIds(ids)); + } +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/ElderController.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/ElderController.java new file mode 100644 index 0000000..492bc93 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/ElderController.java @@ -0,0 +1,126 @@ +package com.zzyl.nursing.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; + +import com.zzyl.common.core.domain.R; +import com.zzyl.nursing.dto.ElderPageQuery; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import lombok.RequiredArgsConstructor; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.zzyl.common.annotation.Log; +import com.zzyl.common.core.controller.BaseController; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.enums.BusinessType; +import com.zzyl.nursing.domain.Elder; +import com.zzyl.nursing.service.IElderService; +import com.zzyl.common.utils.poi.ExcelUtil; +import com.zzyl.common.core.page.TableDataInfo; + +/** + * 老人Controller + * + * @Author: Zhy + * @Date: 2025-02-25 + */ +@Api(tags = "老人管理") +@RestController +@RequestMapping("/nursing/elder") +@RequiredArgsConstructor +public class ElderController extends BaseController { + + private final IElderService elderService; + + /** + * 查询老人列表 + */ + @ApiOperation("查询老人列表") + @PreAuthorize("@ss.hasPermi('nursing:elder:list')") + @GetMapping("/list") + public TableDataInfo> list(@ApiParam("老人查询条件") Elder elder) { + startPage(); + List list = elderService.selectElderList(elder); + return getDataTable(list); + } + + /** + * 导出老人列表 + */ + @ApiOperation("导出老人列表") + @PreAuthorize("@ss.hasPermi('nursing:elder:export')") + @Log(title = "老人", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(@ApiParam(value = "老人查询条件") HttpServletResponse response, Elder elder) { + List list = elderService.selectElderList(elder); + ExcelUtil util = new ExcelUtil<>(Elder.class); + util.exportExcel(response, list, "老人数据"); + } + + /** + * 获取老人详细信息 + */ + @ApiOperation("获取老人详细信息") + @PreAuthorize("@ss.hasPermi('nursing:elder:query')") + @GetMapping(value = "/{id}") + public R getInfo(@ApiParam("老人ID") @PathVariable("id") Long id) { + return R.ok(elderService.selectElderById(id)); + } + + /** + * 新增老人 + */ + @ApiOperation("新增老人") + @PreAuthorize("@ss.hasPermi('nursing:elder:add')") + @Log(title = "老人", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@ApiParam("老人信息") @RequestBody Elder elder) { + return toAjax(elderService.insertElder(elder)); + } + + /** + * 修改老人 + */ + @ApiOperation("修改老人") + @PreAuthorize("@ss.hasPermi('nursing:elder:edit')") + @Log(title = "老人", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@ApiParam("老人信息") @RequestBody Elder elder) { + return toAjax(elderService.updateElder(elder)); + } + + /** + * 删除老人 + */ + @ApiOperation("删除老人") + @PreAuthorize("@ss.hasPermi('nursing:elder:remove')") + @Log(title = "老人", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@ApiParam("老人ID数组") @PathVariable Long[] ids) { + return toAjax(elderService.deleteElderByIds(ids)); + } + + /** + * 查询已经入住的老人列表 + * + * @return: + * @param: + */ + @ApiOperation("查询已经入住的老人列表") + @GetMapping("/pageQuery") + public TableDataInfo pageQuery( + @ApiParam("分页查询老人信息") ElderPageQuery elderPageQuery + ) { + return elderService.pageQuery(elderPageQuery); + } + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/FloorController.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/FloorController.java new file mode 100644 index 0000000..4a6ccba --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/FloorController.java @@ -0,0 +1,124 @@ +package com.zzyl.nursing.controller; + +import cn.hutool.core.lang.tree.Tree; +import com.zzyl.common.annotation.Log; +import com.zzyl.common.core.controller.BaseController; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.core.domain.R; +import com.zzyl.common.enums.BusinessType; +import com.zzyl.nursing.domain.Floor; +import com.zzyl.nursing.service.IFloorService; +import com.zzyl.nursing.vo.FloorVo; +import com.zzyl.nursing.vo.TreeVo; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 楼层Controller + * + * @author ruoyi + * @date 2024-04-26 + */ +@RestController +@RequestMapping("/elder/floor") +@Api(tags = "楼层相关接口") +public class FloorController extends BaseController { + @Autowired + private IFloorService floorService; + + /** + * 查询楼层列表 + */ + @PreAuthorize("@ss.hasPermi('elder:floor:list')") + @GetMapping("/list") + @ApiOperation("查询所有楼层列表") + public R> list() { + List list = floorService.list(); + return R.ok(list); + } + + /** + * 获取楼层详细信息 + */ + @PreAuthorize("@ss.hasPermi('elder:floor:query')") + @GetMapping(value = "/{id}") + @ApiOperation("获取楼层详细信息") + public R getInfo(@ApiParam(value = "楼层ID", required = true) @PathVariable("id") Long id) { + return R.ok(floorService.selectFloorById(id)); + } + + /** + * 新增楼层 + */ + @PreAuthorize("@ss.hasPermi('elder:floor:add')") + @Log(title = "楼层", businessType = BusinessType.INSERT) + @PostMapping + @ApiOperation("新增楼层") + public AjaxResult add(@ApiParam(value = "楼层信息", required = true) @RequestBody Floor floor) { + return toAjax(floorService.insertFloor(floor)); + } + + /** + * 修改楼层 + */ + @ApiOperation("修改楼层") + @PreAuthorize("@ss.hasPermi('elder:floor:edit')") + @Log(title = "楼层", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@ApiParam(value = "楼层信息", required = true) @RequestBody Floor floor) { + return toAjax(floorService.updateFloor(floor)); + } + + /** + * 删除楼层 + */ + @ApiOperation("删除楼层") + @PreAuthorize("@ss.hasPermi('elder:floor:remove')") + @Log(title = "楼层", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@ApiParam(value = "楼层ID", required = true) @PathVariable Long[] ids) { + return toAjax(floorService.deleteFloorByIds(ids)); + } + + @GetMapping("/getAllFloorsWithNur") + @ApiOperation(value = "获取所有楼层 (负责老人)", notes = "无需参数,获取所有楼层,返回楼层信息列表") + public R> getAllFloorsWithNur() { + List list = floorService.selectAllByNur(); + return R.ok(list); + } + + @GetMapping("/getRoomAndBedByBedStatus/{status}") + @ApiOperation(value = "获取所有楼层所有房间中的空床位") + public R> getRoomAndBedByBedStatus( + @ApiParam(value = "床位状态", required = true) @PathVariable("status") Integer status + ) { + List list = floorService.getRoomAndBedByBedStatus(status); + return R.ok(list); + } + + @GetMapping("/getRoomAndBedByBedStatus") + @ApiOperation(value = "获取所有楼层所有房间中的空床位") + public R> getRoomAndBed( ) { + List list = floorService.getRoomAndBed(); + return R.ok(list); + } + + /** + * 获取所有装有智能设备的楼层 + * + * @return: + * @param: + */ + @GetMapping("/getAllFloorsWithDevice") + @ApiOperation(value = "获取所有装有智能设备的楼层") + public R> getAllFloorsWithDevice() { + List list = floorService.getAllFloorsWithDevice(); + return R.ok(list); + } +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/HealthAssessmentController.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/HealthAssessmentController.java new file mode 100644 index 0000000..8c7d715 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/HealthAssessmentController.java @@ -0,0 +1,125 @@ +package com.zzyl.nursing.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; + +import com.zzyl.common.core.domain.R; +import com.zzyl.nursing.dto.HealthAssessmentDto; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import lombok.RequiredArgsConstructor; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.zzyl.common.annotation.Log; +import com.zzyl.common.core.controller.BaseController; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.enums.BusinessType; +import com.zzyl.nursing.domain.HealthAssessment; +import com.zzyl.nursing.service.IHealthAssessmentService; +import com.zzyl.common.utils.poi.ExcelUtil; +import com.zzyl.common.core.page.TableDataInfo; +import org.springframework.web.multipart.MultipartFile; + +/** + * 健康评估Controller + * + * @Author: Zhy + * @Date: 2025-02-28 + */ +@Api(tags = "健康评估管理") +@RestController +@RequestMapping("/nursing/healthAssessment") +@RequiredArgsConstructor +public class HealthAssessmentController extends BaseController { + + private final IHealthAssessmentService healthAssessmentService; + + /** + * 查询健康评估列表 + */ + @ApiOperation("查询健康评估列表") + @PreAuthorize("@ss.hasPermi('nursing:healthAssessment:list')") + @GetMapping("/list") + public TableDataInfo> list(@ApiParam("健康评估查询条件") HealthAssessment healthAssessment) { + startPage(); + List list = healthAssessmentService.selectHealthAssessmentList(healthAssessment); + return getDataTable(list); + } + + /** + * 导出健康评估列表 + */ + @ApiOperation("导出健康评估列表") + @PreAuthorize("@ss.hasPermi('nursing:healthAssessment:export')") + @Log(title = "健康评估", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export( + @ApiParam(value = "健康评估查询条件") HttpServletResponse response, HealthAssessment healthAssessment + ) { + List list = healthAssessmentService.selectHealthAssessmentList(healthAssessment); + ExcelUtil util = new ExcelUtil(HealthAssessment.class); + util.exportExcel(response, list, "健康评估数据"); + } + + /** + * 获取健康评估详细信息 + */ + @ApiOperation("获取健康评估详细信息") + @PreAuthorize("@ss.hasPermi('nursing:healthAssessment:query')") + @GetMapping(value = "/{id}") + public R getInfo(@ApiParam("健康评估ID") @PathVariable("id") Long id) { + return R.ok(healthAssessmentService.selectHealthAssessmentById(id)); + } + + /** + * 新增健康评估 + */ + @ApiOperation("新增健康评估") + @PreAuthorize("@ss.hasPermi('nursing:healthAssessment:add')") + @Log(title = "健康评估", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@ApiParam("健康评估信息") @RequestBody HealthAssessmentDto healthAssessmentDto) { + Long id = healthAssessmentService.insertHealthAssessment(healthAssessmentDto); + return success(id); + } + + /** + * 修改健康评估 + */ + @ApiOperation("修改健康评估") + @PreAuthorize("@ss.hasPermi('nursing:healthAssessment:edit')") + @Log(title = "健康评估", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@ApiParam("健康评估信息") @RequestBody HealthAssessment healthAssessment) { + return toAjax(healthAssessmentService.updateHealthAssessment(healthAssessment)); + } + + /** + * 删除健康评估 + */ + @ApiOperation("删除健康评估") + @PreAuthorize("@ss.hasPermi('nursing:healthAssessment:remove')") + @Log(title = "健康评估", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@ApiParam("健康评估ID数组") @PathVariable Long[] ids) { + return toAjax(healthAssessmentService.deleteHealthAssessmentByIds(ids)); + } + + /** + * 上传体检报告 + */ + @ApiOperation("上传体检报告") + @PostMapping("/upload") + public AjaxResult uploadFile(String idCardNo, MultipartFile file) { + return healthAssessmentService.uploadFile(idCardNo, file); + } + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/NursingElderController.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/NursingElderController.java new file mode 100644 index 0000000..0a1d915 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/NursingElderController.java @@ -0,0 +1,114 @@ +package com.zzyl.nursing.controller; + +import com.zzyl.common.annotation.Log; +import com.zzyl.common.core.controller.BaseController; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.core.page.TableDataInfo; +import com.zzyl.common.enums.BusinessType; +import com.zzyl.common.utils.poi.ExcelUtil; +import com.zzyl.nursing.domain.NursingElder; +import com.zzyl.nursing.dto.NursingElderDto; +import com.zzyl.nursing.service.INursingElderService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * 护理员老人关联Controller + * + * @author ruoyi + * @date 2024-05-28 + */ +@RestController +@RequestMapping("/elder/nursingElder") +@Api(tags = "护理员老人关联相关接口") +public class NursingElderController extends BaseController +{ + @Autowired + private INursingElderService nursingElderService; + + @PostMapping("/setNursing") + @ApiOperation("设置护理员") + public AjaxResult setNursingElder(@RequestBody List nursingElderDtos) + { + return AjaxResult.success(nursingElderService.setNursingElder(nursingElderDtos)); + } + + /** + * 查询护理员老人关联列表 + */ + @PreAuthorize("@ss.hasPermi('elder:elder:list')") + @GetMapping("/list") + @ApiOperation("查询护理员老人关联列表") + public TableDataInfo list(NursingElder nursingElder) + { + startPage(); + List list = nursingElderService.selectNursingElderList(nursingElder); + return getDataTable(list); + } + + /** + * 导出护理员老人关联列表 + */ + @PreAuthorize("@ss.hasPermi('elder:elder:export')") + @Log(title = "护理员老人关联", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, NursingElder nursingElder) + { + List list = nursingElderService.selectNursingElderList(nursingElder); + ExcelUtil util = new ExcelUtil(NursingElder.class); + util.exportExcel(response, list, "护理员老人关联数据"); + } + + /** + * 获取护理员老人关联详细信息 + */ + @PreAuthorize("@ss.hasPermi('elder:elder:query')") + @GetMapping(value = "/{id}") + @ApiOperation("获取护理员老人关联详细信息") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(nursingElderService.selectNursingElderById(id)); + } + + /** + * 新增护理员老人关联 + */ + @PreAuthorize("@ss.hasPermi('elder:elder:add')") + @Log(title = "护理员老人关联", businessType = BusinessType.INSERT) + @PostMapping + @ApiOperation("新增护理员老人关联") + public AjaxResult add(@RequestBody NursingElder nursingElder) + { + return toAjax(nursingElderService.insertNursingElder(nursingElder)); + } + + /** + * 修改护理员老人关联 + */ + @ApiOperation("修改护理员老人关联") + @PreAuthorize("@ss.hasPermi('elder:elder:edit')") + @Log(title = "护理员老人关联", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody NursingElder nursingElder) + { + return toAjax(nursingElderService.updateNursingElder(nursingElder)); + } + + /** + * 删除护理员老人关联 + */ + @ApiOperation("删除护理员老人关联") + @PreAuthorize("@ss.hasPermi('elder:elder:remove')") + @Log(title = "护理员老人关联", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(nursingElderService.deleteNursingElderByIds(ids)); + } +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/NursingLevelController.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/NursingLevelController.java new file mode 100644 index 0000000..58e0b38 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/NursingLevelController.java @@ -0,0 +1,121 @@ +package com.zzyl.nursing.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; + +import com.zzyl.common.core.domain.R; +import com.zzyl.nursing.vo.NursingLevelVo; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import lombok.RequiredArgsConstructor; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.zzyl.common.annotation.Log; +import com.zzyl.common.core.controller.BaseController; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.enums.BusinessType; +import com.zzyl.nursing.domain.NursingLevel; +import com.zzyl.nursing.service.INursingLevelService; +import com.zzyl.common.utils.poi.ExcelUtil; +import com.zzyl.common.core.page.TableDataInfo; + +/** + * 护理等级Controller + * + * @Author: alexis + * @Date: 2024-12-30 + */ +@Api(tags = "护理等级管理") +@RestController +@RequestMapping("/nursing/level") +@RequiredArgsConstructor +public class NursingLevelController extends BaseController { + + private final INursingLevelService nursingLevelService; + + /** + * 查询护理等级列表 + */ + @ApiOperation("查询护理等级列表") + @PreAuthorize("@ss.hasPermi('nursing:level:list')") + @GetMapping("/list") + public TableDataInfo> list(@ApiParam("护理等级查询条件") NursingLevel nursingLevel) { + startPage(); + List list = nursingLevelService.selectNursingLevelVoList(nursingLevel); + return getDataTable(list); + } + + /** + * 导出护理等级列表 + */ + @ApiOperation("导出护理等级列表") + @PreAuthorize("@ss.hasPermi('nursing:level:export')") + @Log(title = "护理等级", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(@ApiParam(value = "护理等级查询条件") HttpServletResponse response, NursingLevel nursingLevel) { + List list = nursingLevelService.selectNursingLevelList(nursingLevel); + ExcelUtil util = new ExcelUtil(NursingLevel.class); + util.exportExcel(response, list, "护理等级数据"); + } + + /** + * 获取护理等级详细信息 + */ + @ApiOperation("获取护理等级详细信息") + @PreAuthorize("@ss.hasPermi('nursing:level:query')") + @GetMapping(value = "/{id}") + public R getInfo(@ApiParam("护理等级ID") @PathVariable("id") Long id) { + return R.ok(nursingLevelService.selectNursingLevelById(id)); + } + + /** + * 新增护理等级 + */ + @ApiOperation("新增护理等级") + @PreAuthorize("@ss.hasPermi('nursing:level:add')") + @Log(title = "护理等级", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@ApiParam("护理等级信息") @RequestBody NursingLevel nursingLevel) { + return toAjax(nursingLevelService.insertNursingLevel(nursingLevel)); + } + + /** + * 修改护理等级 + */ + @ApiOperation("修改护理等级") + @PreAuthorize("@ss.hasPermi('nursing:level:edit')") + @Log(title = "护理等级", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@ApiParam("护理等级信息") @RequestBody NursingLevel nursingLevel) { + return toAjax(nursingLevelService.updateNursingLevel(nursingLevel)); + } + + /** + * 删除护理等级 + */ + @ApiOperation("删除护理等级") + @PreAuthorize("@ss.hasPermi('nursing:level:remove')") + @Log(title = "护理等级", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@ApiParam("护理等级ID数组") @PathVariable Long[] ids) { + return toAjax(nursingLevelService.deleteNursingLevelByIds(ids)); + } + + /** + * 查询所有已启用的护理等级 + */ + @ApiOperation("查询所有已启用的护理等级") + @Log(title = "护理等级", businessType = BusinessType.DELETE) + @GetMapping("/all") + public R> getByEnableLevel() { + return R.ok(nursingLevelService.selectByEnable()); + } +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/NursingPlanController.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/NursingPlanController.java new file mode 100644 index 0000000..2ad0795 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/NursingPlanController.java @@ -0,0 +1,128 @@ +package com.zzyl.nursing.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; + +import com.zzyl.common.core.domain.R; +import com.zzyl.nursing.dto.NursingPlanDto; +import com.zzyl.nursing.vo.NursingPlanVo; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.zzyl.common.annotation.Log; +import com.zzyl.common.core.controller.BaseController; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.enums.BusinessType; +import com.zzyl.nursing.domain.NursingPlan; +import com.zzyl.nursing.service.INursingPlanService; +import com.zzyl.common.utils.poi.ExcelUtil; +import com.zzyl.common.core.page.TableDataInfo; + +/** + * 护理计划Controller + * + * @author alexis + * @date 2024-12-30 + */ +@Api(tags = "护理计划管理") +@RestController +@RequestMapping("/nursing/plan") +public class NursingPlanController extends BaseController +{ + @Autowired + private INursingPlanService nursingPlanService; + + /** + * 查询护理计划列表 + */ + @ApiOperation("查询护理计划列表") + @PreAuthorize("@ss.hasPermi('nursing:plan:list')") + @GetMapping("/list") + public TableDataInfo> list(@ApiParam("护理计划查询条件") NursingPlan nursingPlan) + { + startPage(); + List list = nursingPlanService.selectNursingPlanList(nursingPlan); + return getDataTable(list); + } + + /** + * 导出护理计划列表 + */ + @ApiOperation("导出护理计划列表") + @PreAuthorize("@ss.hasPermi('nursing:plan:export')") + @Log(title = "护理计划", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(@ApiParam(value = "护理计划查询条件") HttpServletResponse response, NursingPlan nursingPlan) + { + List list = nursingPlanService.selectNursingPlanList(nursingPlan); + ExcelUtil util = new ExcelUtil(NursingPlan.class); + util.exportExcel(response, list, "护理计划数据"); + } + + /** + * 获取护理计划详细信息 + */ + @ApiOperation("获取护理计划详细信息") + @PreAuthorize("@ss.hasPermi('nursing:plan:query')") + @GetMapping(value = "/{id}") + public R getInfo(@ApiParam("护理计划ID") @PathVariable("id") Long id) + { + return R.ok(nursingPlanService.selectNursingPlanById(id)); + } + + /** + * 新增护理计划 + */ + @ApiOperation("新增护理计划") + @PreAuthorize("@ss.hasPermi('nursing:plan:add')") + @Log(title = "护理计划", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@ApiParam("护理计划信息") @RequestBody NursingPlanDto nursingPlanDto) + { + return toAjax(nursingPlanService.insertNursingPlan(nursingPlanDto)); + } + + /** + * 修改护理计划 + */ + @ApiOperation("修改护理计划") + @PreAuthorize("@ss.hasPermi('nursing:plan:edit')") + @Log(title = "护理计划", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@ApiParam("护理计划信息") @RequestBody NursingPlanDto nursingPlanDto) + { + return toAjax(nursingPlanService.updateNursingPlan(nursingPlanDto)); + } + + /** + * 删除护理计划 + */ + @ApiOperation("删除护理计划") + @PreAuthorize("@ss.hasPermi('nursing:plan:remove')") + @Log(title = "护理计划", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@ApiParam("护理计划ID数组") @PathVariable Long[] ids) + { + return toAjax(nursingPlanService.deleteNursingPlanByIds(ids)); + } + + /** + * 查询所有护理计划 + */ + @GetMapping("/all") + @ApiOperation(value = "获取所有护理计划") + public R> listAll() + { + return R.ok(nursingPlanService.getAllNursingPlans()); + } +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/NursingProjectController.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/NursingProjectController.java new file mode 100644 index 0000000..5563648 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/NursingProjectController.java @@ -0,0 +1,122 @@ +package com.zzyl.nursing.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; + +import com.zzyl.common.core.domain.R; +import com.zzyl.nursing.vo.NursingProjectVo; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.zzyl.common.annotation.Log; +import com.zzyl.common.core.controller.BaseController; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.enums.BusinessType; +import com.zzyl.nursing.domain.NursingProject; +import com.zzyl.nursing.service.INursingProjectService; +import com.zzyl.common.utils.poi.ExcelUtil; +import com.zzyl.common.core.page.TableDataInfo; + +/** + * 护理项目Controller + * + * @author alexis + * @date 2024-12-30 + */ +@Api(tags = "护理项目管理") +@RestController +@RequestMapping("/nursing/project") +public class NursingProjectController extends BaseController +{ + @Autowired + private INursingProjectService nursingProjectService; + + /** + * 查询护理项目列表 + */ + @ApiOperation("查询护理项目列表") + @PreAuthorize("@ss.hasPermi('nursing:project:list')") + @GetMapping("/list") + public TableDataInfo> list(@ApiParam("护理项目查询条件") NursingProject nursingProject) + { + startPage(); + List list = nursingProjectService.selectNursingProjectList(nursingProject); + return getDataTable(list); + } + + /** + * 导出护理项目列表 + */ + @ApiOperation("导出护理项目列表") + @PreAuthorize("@ss.hasPermi('nursing:project:export')") + @Log(title = "护理项目", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(@ApiParam(value = "护理项目查询条件") HttpServletResponse response, NursingProject nursingProject) + { + List list = nursingProjectService.selectNursingProjectList(nursingProject); + ExcelUtil util = new ExcelUtil(NursingProject.class); + util.exportExcel(response, list, "护理项目数据"); + } + + /** + * 获取护理项目详细信息 + */ + @ApiOperation("获取护理项目详细信息") + @PreAuthorize("@ss.hasPermi('nursing:project:query')") + @GetMapping(value = "/{id}") + public R getInfo(@ApiParam("护理项目ID") @PathVariable("id") Long id) + { + return R.ok(nursingProjectService.selectNursingProjectById(id)); + } + + /** + * 新增护理项目 + */ + @ApiOperation("新增护理项目") + @PreAuthorize("@ss.hasPermi('nursing:project:add')") + @Log(title = "护理项目", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@ApiParam("护理项目信息") @RequestBody NursingProject nursingProject) + { + return toAjax(nursingProjectService.insertNursingProject(nursingProject)); + } + + /** + * 修改护理项目 + */ + @ApiOperation("修改护理项目") + @PreAuthorize("@ss.hasPermi('nursing:project:edit')") + @Log(title = "护理项目", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@ApiParam("护理项目信息") @RequestBody NursingProject nursingProject) + { + return toAjax(nursingProjectService.updateNursingProject(nursingProject)); + } + + /** + * 删除护理项目 + */ + @ApiOperation("删除护理项目") + @PreAuthorize("@ss.hasPermi('nursing:project:remove')") + @Log(title = "护理项目", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@ApiParam("护理项目ID数组") @PathVariable Long[] ids) + { + return toAjax(nursingProjectService.deleteNursingProjectByIds(ids)); + } + + @GetMapping("/all") + public R> getAllProjects() { + return R.ok(nursingProjectService.getAllProjects()); + } +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/NursingTaskController.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/NursingTaskController.java new file mode 100644 index 0000000..ae16724 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/NursingTaskController.java @@ -0,0 +1,135 @@ +package com.zzyl.nursing.controller; + +import com.zzyl.common.annotation.Log; +import com.zzyl.common.core.controller.BaseController; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.core.domain.R; +import com.zzyl.common.core.page.TableDataInfo; +import com.zzyl.common.enums.BusinessType; +import com.zzyl.common.utils.poi.ExcelUtil; +import com.zzyl.nursing.domain.NursingTask; +import com.zzyl.nursing.dto.NursingTaskCancelDto; +import com.zzyl.nursing.dto.NursingTaskDoDto; +import com.zzyl.nursing.dto.NursingTaskDto; +import com.zzyl.nursing.dto.NursingTaskUpdateDto; +import com.zzyl.nursing.service.INursingTaskService; +import com.zzyl.nursing.vo.NursingTaskVo; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * 护理任务Controller + * + * @author ruoyi + * @date 2024-09-27 + */ +@RestController +@RequestMapping("/nursing/nursingTask") +@Api(tags = "护理任务的接口") +public class NursingTaskController extends BaseController +{ + @Autowired + // @Qualifier("nursingTaskServiceImpl") + private INursingTaskService nursingTaskService; + + /** + * 查询护理任务列表 + */ + @ApiOperation("查询护理任务列表") + @GetMapping("/list") + public TableDataInfo list(NursingTaskDto nursingTaskDto) + { + return nursingTaskService.list(nursingTaskDto); + } + + /** + * 导出护理任务列表 + */ + @ApiOperation("导出护理任务列表") + @Log(title = "护理任务", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, NursingTask nursingTask) + { + List list = nursingTaskService.selectNursingTaskList(nursingTask); + ExcelUtil util = new ExcelUtil(NursingTask.class); + util.exportExcel(response, list, "护理任务数据"); + } + + /** + * 获取护理任务详细信息 + */ + @ApiOperation("获取护理任务详细信息") + @GetMapping(value = "/{id}") + public R getInfo(@ApiParam(value = "护理任务ID", required = true) + @PathVariable("id") Long id) + { + return R.ok(nursingTaskService.selectNursingTaskById(id)); + } + + /** + * 新增护理任务 + */ + @ApiOperation("新增护理任务") + @Log(title = "护理任务", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@ApiParam(value = "护理任务实体") + @RequestBody NursingTask nursingTask) + { + return toAjax(nursingTaskService.insertNursingTask(nursingTask)); + } + + /** + * 修改护理任务 + */ + @ApiOperation("修改护理任务") + @Log(title = "护理任务", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@ApiParam(value = "护理任务实体") + @RequestBody NursingTask nursingTask) + { + return toAjax(nursingTaskService.updateNursingTask(nursingTask)); + } + + /** + * 删除护理任务 + */ + @ApiOperation("删除护理任务") + @Log(title = "护理任务", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(nursingTaskService.deleteNursingTaskByIds(ids)); + } + + @ApiOperation("取消任务") + @PutMapping("/cancel") + public AjaxResult cancel(@ApiParam("取消原因") @RequestBody NursingTaskCancelDto nursingTaskCancelDto) { + nursingTaskService.cancel(nursingTaskCancelDto); + return success(); + } + + @ApiOperation("执行任务") + @PutMapping("/do") + public AjaxResult doTask(@ApiParam("执行任务dto") @RequestBody NursingTaskDoDto nursingTaskDoDto) { + nursingTaskService.doTask(nursingTaskDoDto); + return success(); + } + + @ApiOperation("任务改期") + @PutMapping("/updateTime") + public AjaxResult updateTime(@ApiParam("执行任务dto") @RequestBody NursingTaskUpdateDto nursingTaskUpdateDto) { + nursingTaskService.updateTime(nursingTaskUpdateDto); + return success(); + } + + + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/RoomController.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/RoomController.java new file mode 100644 index 0000000..e78eed1 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/RoomController.java @@ -0,0 +1,124 @@ +package com.zzyl.nursing.controller; + +import com.zzyl.common.annotation.Log; +import com.zzyl.common.core.controller.BaseController; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.core.domain.R; +import com.zzyl.common.core.page.TableDataInfo; +import com.zzyl.common.enums.BusinessType; +import com.zzyl.nursing.domain.Room; +import com.zzyl.nursing.service.IRoomService; +import com.zzyl.nursing.vo.RoomVo; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 房间Controller + * + * @author ruoyi + * @date 2024-04-26 + */ +@RestController +@RequestMapping("/elder/room") +@Api(tags = "房间相关接口") +public class RoomController extends BaseController { + @Autowired + private IRoomService roomService; + + @GetMapping("/getRoomsWithNurByFloorId/{floorId}") + @ApiOperation("获取所有房间(负责老人)") + public R> getRoomsWithNurByFloorId(@PathVariable Long floorId) { + List list = roomService.getRoomsWithNurByFloorId(floorId); + return R.ok(list); + } + + @GetMapping("/getRoomsByFloorId/{floorId}") + @ApiOperation("获取所有房间(入住配置)") + public R> getRoomsByFloorId(@ApiParam(value = "楼层ID", required = true) @PathVariable Long floorId) { + List list = roomService.getRoomsByFloorId(floorId); + return R.ok(list); + } + + /** + * 查询房间列表 + */ + @PreAuthorize("@ss.hasPermi('elder:room:list')") + @GetMapping("/list") + @ApiOperation("查询房间列表") + public TableDataInfo list(@ApiParam(value = "房间信息", required = true) Room room) { + startPage(); + List list = roomService.selectRoomList(room); + return getDataTable(list); + } + + /** + * 获取房间详细信息 + */ + @PreAuthorize("@ss.hasPermi('elder:room:query')") + @GetMapping(value = "/{id}") + @ApiOperation("获取房间详细信息") + public R getInfo(@ApiParam(value = "房间ID", required = true) @PathVariable("id") Long id) { + return R.ok(roomService.selectRoomById(id)); + } + + /** + * 新增房间 + */ + @PreAuthorize("@ss.hasPermi('elder:room:add')") + @Log(title = "房间", businessType = BusinessType.INSERT) + @PostMapping + @ApiOperation("新增房间") + public AjaxResult add(@ApiParam(value = "房间信息", required = true) @RequestBody Room room) { + return toAjax(roomService.insertRoom(room)); + } + + /** + * 修改房间 + */ + @ApiOperation("修改房间") + @PreAuthorize("@ss.hasPermi('elder:room:edit')") + @Log(title = "房间", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@ApiParam(value = "房间信息", required = true) @RequestBody Room room) { + return toAjax(roomService.updateRoom(room)); + } + + /** + * 删除房间 + */ + @ApiOperation("删除房间") + @PreAuthorize("@ss.hasPermi('elder:room:remove')") + @Log(title = "房间", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@ApiParam(value = "房间ID数组", required = true) @PathVariable Long[] ids) { + return toAjax(roomService.deleteRoomByIds(ids)); + } + + /** + * 根据房间id查询 房间 数据 + */ + @GetMapping(value = "/one/{id}") + @ApiOperation("根据房间id查询房间数据") + public R getRoomPriceByRoomId(@ApiParam(value = "房间ID", required = true) @PathVariable("id") Long id) { + return R.ok(roomService.getRoomPriceByRoomId(id)); + } + + /** + * 获取房间中的智能设备及数据 + * + * @return: + * @param: + */ + @GetMapping(value = "/getRoomsWithDeviceByFloorId/{floorId}") + @ApiOperation("根据房间id查询房间数据") + public R> getRoomsWithDeviceByFloorId(@ApiParam(value = "房间ID", required = true) @PathVariable("floorId") Long floorId) { + return R.ok(roomService.getRoomsWithDeviceByFloorId(floorId)); + } + +} \ No newline at end of file diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/RoomTypeController.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/RoomTypeController.java new file mode 100644 index 0000000..aaa6f8a --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/RoomTypeController.java @@ -0,0 +1,110 @@ +package com.zzyl.nursing.controller; + +import com.zzyl.common.annotation.Log; +import com.zzyl.common.core.controller.BaseController; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.core.page.TableDataInfo; +import com.zzyl.common.enums.BusinessType; +import com.zzyl.common.utils.poi.ExcelUtil; +import com.zzyl.nursing.domain.RoomType; +import com.zzyl.nursing.service.IRoomTypeService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * 房型Controller + * + * @author ruoyi + * @date 2024-04-26 + */ +@RestController +@RequestMapping("/elder/roomType") +@Api(tags = "房型相关接口") +public class RoomTypeController extends BaseController +{ + @Autowired + private IRoomTypeService roomTypeService; + + /** + * 查询房型列表 + */ + @GetMapping("/list") + @ApiOperation("查询房型列表") + public TableDataInfo list(RoomType roomType) + { + startPage(); + List list = roomTypeService.selectRoomTypeList(roomType); + return getDataTable(list); + } + + /** + * 查询房型列表 + */ + @GetMapping("/listAll") + @ApiOperation("查询所有房型列表") + public AjaxResult list() + { + List list = roomTypeService.list(); + return success(list); + } + + /** + * 导出房型列表 + */ + @Log(title = "房型", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, RoomType roomType) + { + List list = roomTypeService.selectRoomTypeList(roomType); + ExcelUtil util = new ExcelUtil(RoomType.class); + util.exportExcel(response, list, "房型数据"); + } + + /** + * 获取房型详细信息 + */ + @GetMapping(value = "/{id}") + @ApiOperation("获取房型详细信息") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(roomTypeService.selectRoomTypeById(id)); + } + + /** + * 新增房型 + */ + @Log(title = "房型", businessType = BusinessType.INSERT) + @PostMapping + @ApiOperation("新增房型") + public AjaxResult add(@RequestBody RoomType roomType) + { + return toAjax(roomTypeService.insertRoomType(roomType)); + } + + /** + * 修改房型 + */ + @ApiOperation("修改房型") + @Log(title = "房型", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody RoomType roomType) + { + return toAjax(roomTypeService.updateRoomType(roomType)); + } + + /** + * 删除房型 + */ + @ApiOperation("删除房型") + @Log(title = "房型", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(roomTypeService.deleteRoomTypeByIds(ids)); + } +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/member/FamilyMemberController.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/member/FamilyMemberController.java new file mode 100644 index 0000000..e07fc83 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/member/FamilyMemberController.java @@ -0,0 +1,90 @@ +package com.zzyl.nursing.controller.member; + +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.core.domain.R; +import com.zzyl.nursing.dto.ElderDto; +import com.zzyl.nursing.dto.QueryDevicePropertyDto; +import com.zzyl.nursing.dto.UserLoginRequestDto; +import com.zzyl.nursing.vo.DevicePropertyVo; +import com.zzyl.nursing.vo.FamilyMemberElderVo; +import com.zzyl.nursing.vo.LoginVo; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; +import com.zzyl.common.core.controller.BaseController; +import com.zzyl.nursing.service.IFamilyMemberService; + +import java.util.List; +import java.util.Map; + +/** + * 老人家属Controller + * + * @author Zhy + * @date 2025-03-03 + */ +@Api(tags = "老人家属管理") +@RestController +@RequestMapping("/member/user") +@RequiredArgsConstructor +public class FamilyMemberController extends BaseController { + + private final IFamilyMemberService familyMemberService; + + /** + * 小程序登录 + * + * @return: + * @param: userLoginRequestDto 用户登录请求参数 + */ + @PostMapping("/login") + @ApiOperation("小程序登录") + public R login(@RequestBody UserLoginRequestDto userLoginRequestDto) { + LoginVo loginVo = familyMemberService.login(userLoginRequestDto); + return R.ok(loginVo); + } + + @PostMapping("/add") + @ApiOperation("绑定老人家属") + public AjaxResult addMember(@RequestBody ElderDto elderDto) { + familyMemberService.addMember(elderDto); + return AjaxResult.success(); + } + + @GetMapping("/my") + @ApiOperation("查询当前登录用户的老人家属信息") + public AjaxResult getMyElder() { + List elderDtoList = familyMemberService.getMyElder(); + return AjaxResult.success(elderDtoList); + } + + @GetMapping("/list-by-page") + @ApiOperation("分页查询当前登录用户的老人家属信息") + private AjaxResult listByPage(@RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "10") Integer pageSize) { + List familyMemberElderVoList = familyMemberService.listByPage(pageNum, pageSize); + return AjaxResult.success(familyMemberElderVoList); + } + + @PostMapping("/QueryDevicePropertyStatus") + @ApiOperation("查询设备属性状态") + private AjaxResult queryDevicePropertyStatus(@RequestBody QueryDevicePropertyDto queryDevicePropertyDto) { + DevicePropertyVo devicePropertyVo = familyMemberService.queryDevicePropertyStatus(queryDevicePropertyDto); + return AjaxResult.success(devicePropertyVo); + } + + @GetMapping("/queryDeviceDataListByDay") + @ApiOperation("按天统计查询指标数据") + private AjaxResult queryDeviceDataListByDay(String functionId, String iotId, Long startTime, Long endTime) { + List> familyMemberElderVoList = familyMemberService.queryDeviceDataListByDay(functionId, iotId, startTime, endTime); + return AjaxResult.success(familyMemberElderVoList); + } + + @GetMapping("/queryDeviceDataListByWeek") + @ApiOperation("按周统计查询指标数据") + private AjaxResult queryDeviceDataListByWeek(String functionId, String iotId, Long startTime, Long endTime) { + List> familyMemberElderVoList = familyMemberService.queryDeviceDataListByWeek(functionId, iotId, startTime, endTime); + return AjaxResult.success(familyMemberElderVoList); + } + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/member/MemberOrderProjectController.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/member/MemberOrderProjectController.java new file mode 100644 index 0000000..18d7a8e --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/member/MemberOrderProjectController.java @@ -0,0 +1,53 @@ +package com.zzyl.nursing.controller.member; + +import com.zzyl.common.core.controller.BaseController; +import com.zzyl.common.core.domain.R; +import com.zzyl.common.core.page.TableDataInfo; +import com.zzyl.nursing.domain.NursingProject; +import com.zzyl.nursing.service.INursingProjectService; +import io.swagger.annotations.Api; + +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +/** + * 服务项目控制层 + * + * @author Zhy + * @version 1.0 + * @date 2025-03-05 15:48 + */ +@RestController +@RequestMapping("/member/orders/project") +@Slf4j +@Api(tags = "服务项目控制层") +@RequiredArgsConstructor +public class MemberOrderProjectController extends BaseController { + + private final INursingProjectService nursingProjectService; + + @ApiOperation("分页查询护理项目列表") + @GetMapping("/page") + public TableDataInfo> selectPageProject(@ApiParam("护理项目查询条件") NursingProject nursingProject) { + // 开始分页 + startPage(); + + List list = nursingProjectService.selectNursingProjectList(nursingProject); + return getDataTable(list); + } + + @ApiOperation("根据编号查询护理项目信息") + @GetMapping("/{id}") + public R selectPageProjectById(@ApiParam("护理项目id") @PathVariable("id") Long id) { + return R.ok(nursingProjectService.selectNursingProjectById(id)); + } + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/member/MemberReservationController.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/member/MemberReservationController.java new file mode 100644 index 0000000..b0170de --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/member/MemberReservationController.java @@ -0,0 +1,107 @@ +package com.zzyl.nursing.controller.member; + +import com.zzyl.common.core.controller.BaseController; +import com.zzyl.common.core.domain.R; +import com.zzyl.common.core.page.TableDataInfo; +import com.zzyl.common.utils.UserThreadLocal; +import com.zzyl.nursing.domain.MemberReservation; +import com.zzyl.nursing.service.IMemberReservationService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 参观预约控制层 + * + * @author Zhy + * @version 1.0 + * @date 2025-03-05 14:26 + */ +@RestController +@RequestMapping("/member/reservation") +@Api(tags = "预约信息相关接口") +@Slf4j +@RequiredArgsConstructor +public class MemberReservationController extends BaseController { + + private final IMemberReservationService memberReservationService; + + /** + * 查询当天取消预约数量 + * + * @return: + * @param: + */ + @GetMapping("/cancelled-count") + @ApiOperation("查询取消预约数量") + public R getCancelledReservationCount() { + log.info("查询取消预约数量"); + Integer count = memberReservationService.selectReservationCount(); + return R.ok(count); + } + + /** + * 查询每个时间段剩余预约次数 + * + * @return: + * @param: + */ + // @GetMapping("/countByTime") + // @ApiOperation("查询每个时间段剩余预约次数") + // public R selectReservationCountByTime(@ApiParam("预约时间") String time) { + // Integer count = memberReservationService.selectReservationCountByTime(); + // return R.ok(count); + // } + + /** + * 新增预约 + * + * @return: + * @param: + */ + @PostMapping + @ApiOperation("新增预约") + public R insertReservation( + @ApiParam("预约信息") @RequestBody MemberReservation memberReservation + ) { + log.info("新增预约,memberReservation={}", memberReservation); + memberReservationService.insertReservation(memberReservation); + return R.ok(); + } + + /** + * 分页查询预约 + * + * @return: + * @param: + */ + @GetMapping("/page") + @ApiOperation("分页查询预约") + public R selectPageReservation( + @ApiParam("预约信息") MemberReservation memberReservation + ) { + startPage(); + List list = memberReservationService.selectReservationList(memberReservation); + return R.ok(getDataTable(list)); + } + + /** + * 取消预约 + * + * @return: + * @param: + */ + @PutMapping("/{id}/cancel") + @ApiOperation("取消预约") + public R cancelReservation(@ApiParam("预约id") @PathVariable("id") Long id) { + log.info("取消预约,id={}", id); + memberReservationService.updateReservationById(id); + return R.ok(); + } + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/member/MemberRoomTypeController.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/member/MemberRoomTypeController.java new file mode 100644 index 0000000..601fb77 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/controller/member/MemberRoomTypeController.java @@ -0,0 +1,40 @@ +package com.zzyl.nursing.controller.member; + +import com.zzyl.common.core.controller.BaseController; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.nursing.domain.RoomType; +import com.zzyl.nursing.service.IRoomTypeService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +/** + * 客户房型管理 + * + * @author Zhy + * @version 1.0 + * @date 2025-03-03 15:15 + */ +@RestController +@RequestMapping("/member/roomTypes") +@Api(tags = "客户房型管理") +@RequiredArgsConstructor +public class MemberRoomTypeController extends BaseController { + + private final IRoomTypeService roomTypeService; + + @GetMapping + @ApiOperation("根据状态查询房型") + public AjaxResult findRoomTypeListByStatus(Integer status) { + + List roomTypeVoList = roomTypeService.findRoomTypeListByStatus(status); + return success(roomTypeVoList); + } + +} + diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/AlertData.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/AlertData.java new file mode 100644 index 0000000..1fb1076 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/AlertData.java @@ -0,0 +1,127 @@ +package com.zzyl.nursing.domain; + +import java.time.LocalDateTime; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.AllArgsConstructor; +import com.zzyl.common.annotation.Excel; +import com.zzyl.common.core.domain.BaseEntity; + +/** + * 报警数据对象 alert_data + * + * @author Zhy + * @date 2025-03-11 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel("报警数据实体") +public class AlertData extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + // 主键 + @ApiModelProperty("主键") + private Long id; + + // 物联网设备id + @Excel(name = "物联网设备id") + @ApiModelProperty("物联网设备id") + private String iotId; + + // 设备名称 + @Excel(name = "设备名称") + @ApiModelProperty("设备名称") + private String deviceName; + + // 所属产品key + @Excel(name = "所属产品key") + @ApiModelProperty("所属产品key") + private String productKey; + + // 产品名称 + @Excel(name = "产品名称") + @ApiModelProperty("产品名称") + private String productName; + + // 功能标识符 + @Excel(name = "功能标识符") + @ApiModelProperty("功能标识符") + private String functionId; + + // 接入位置 + @Excel(name = "接入位置") + @ApiModelProperty("接入位置") + private String accessLocation; + + // 位置类型 0:随身设备 1:固定设备 + @Excel(name = "位置类型 0:随身设备 1:固定设备") + @ApiModelProperty("位置类型 0:随身设备 1:固定设备") + private Integer locationType; + + // 物理位置类型 0楼层 1房间 2床位 + @Excel(name = "物理位置类型 0楼层 1房间 2床位") + @ApiModelProperty("物理位置类型 0楼层 1房间 2床位") + private Integer physicalLocationType; + + // 位置备注 + @Excel(name = "位置备注") + @ApiModelProperty("位置备注") + private String deviceDescription; + + // 数据值 + @Excel(name = "数据值") + @ApiModelProperty("数据值") + private String dataValue; + + // 报警规则id + @Excel(name = "报警规则id") + @ApiModelProperty("报警规则id") + private Long alertRuleId; + + // 报警原因,格式:功能名称+运算符+阈值+持续周期+聚合周期 + @Excel(name = "报警原因,格式:功能名称+运算符+阈值+持续周期+聚合周期") + @ApiModelProperty("报警原因,格式:功能名称+运算符+阈值+持续周期+聚合周期") + private String alertReason; + + // 处理结果 + @Excel(name = "处理结果") + @ApiModelProperty("处理结果") + private String processingResult; + + // 处理人id + @Excel(name = "处理人id") + @ApiModelProperty("处理人id") + private Long processorId; + + // 处理人名称 + @Excel(name = "处理人名称") + @ApiModelProperty("处理人名称") + private String processorName; + + // 处理时间 + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "处理时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty("处理时间") + private LocalDateTime processingTime; + + // 报警数据类型,0:老人异常数据,1:设备异常数据 + @Excel(name = "报警数据类型,0:老人异常数据,1:设备异常数据") + @ApiModelProperty("报警数据类型,0:老人异常数据,1:设备异常数据") + private Integer type; + + // 状态,0:待处理,1:已处理 + @Excel(name = "状态,0:待处理,1:已处理") + @ApiModelProperty("状态,0:待处理,1:已处理") + private Integer status; + + // 接收人id + @Excel(name = "接收人id") + @ApiModelProperty("接收人id") + private Long userId; + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/AlertRule.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/AlertRule.java new file mode 100644 index 0000000..7184905 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/AlertRule.java @@ -0,0 +1,109 @@ +package com.zzyl.nursing.domain; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.AllArgsConstructor; +import com.zzyl.common.annotation.Excel; +import com.zzyl.common.core.domain.BaseEntity; + +/** + * 报警规则对象 alert_rule + * + * @author Zhy + * @date 2025-03-11 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel("报警规则实体") +public class AlertRule extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + // 主键ID + @ApiModelProperty("主键ID") + private Long id; + + // 所属产品的key + @Excel(name = "所属产品的key") + @ApiModelProperty("所属产品的key") + private String productKey; + + // 产品名称 + @Excel(name = "产品名称") + @ApiModelProperty("产品名称") + private String productName; + + // 模块的key + @Excel(name = "模块的key") + @ApiModelProperty("模块的key") + private String moduleId; + + // 模块名称 + @Excel(name = "模块名称") + @ApiModelProperty("模块名称") + private String moduleName; + + // 功能名称 + @Excel(name = "功能名称") + @ApiModelProperty("功能名称") + private String functionName; + + // 功能标识 + @Excel(name = "功能标识") + @ApiModelProperty("功能标识") + private String functionId; + + // 物联网设备id + @Excel(name = "物联网设备id") + @ApiModelProperty("物联网设备id") + private String iotId; + + // 设备名称 + @Excel(name = "设备名称") + @ApiModelProperty("设备名称") + private String deviceName; + + // 报警数据类型,0:老人异常数据,1:设备异常数据 + @Excel(name = "报警数据类型,0:老人异常数据,1:设备异常数据") + @ApiModelProperty("报警数据类型,0:老人异常数据,1:设备异常数据") + private Integer alertDataType; + + // 告警规则名称 + @Excel(name = "告警规则名称") + @ApiModelProperty("告警规则名称") + private String alertRuleName; + + // 运算符 + @Excel(name = "运算符") + @ApiModelProperty("运算符") + private String operator; + + // 阈值 + @Excel(name = "阈值") + @ApiModelProperty("阈值") + private Double value; + + // 持续周期 + @Excel(name = "持续周期") + @ApiModelProperty("持续周期") + private Integer duration; + + // 报警生效时段 + @Excel(name = "报警生效时段") + @ApiModelProperty("报警生效时段") + private String alertEffectivePeriod; + + // 报警沉默周期 + @Excel(name = "报警沉默周期") + @ApiModelProperty("报警沉默周期") + private Integer alertSilentPeriod; + + // 0 禁用 1启用 + @Excel(name = "0 禁用 1启用") + @ApiModelProperty("0 禁用 1启用") + private Integer status; + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/Bed.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/Bed.java new file mode 100644 index 0000000..5ce1802 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/Bed.java @@ -0,0 +1,48 @@ +package com.zzyl.nursing.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.zzyl.common.annotation.Excel; +import com.zzyl.common.core.domain.BaseEntity; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 床位对象 bed + * + * @author ruoyi + * @date 2024-04-26 + */ +@Data +@ApiModel("床位实体对象") +public class Bed extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 床位ID */ + @ApiModelProperty(value = "床位ID") + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** 床位编号 */ + @Excel(name = "床位编号") + @ApiModelProperty(value = "床位编号") + private String bedNumber; + + /** 床位状态: 未入住0, 已入住1 入住申请中2 */ + @Excel(name = "床位状态: 未入住0, 已入住1 入住申请中2") + @ApiModelProperty(value = "床位状态: 未入住0, 已入住1 入住申请中2") + private Integer bedStatus; + + /** 床位号 */ + @Excel(name = "床位号") + @ApiModelProperty(value = "床位号") + private Long sort; + + /** 房间ID */ + @Excel(name = "房间ID") + @ApiModelProperty(value = "房间ID") + private Long roomId; + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/CheckIn.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/CheckIn.java new file mode 100644 index 0000000..ff250a2 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/CheckIn.java @@ -0,0 +1,78 @@ +package com.zzyl.nursing.domain; + +import java.time.LocalDateTime; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.AllArgsConstructor; +import com.zzyl.common.annotation.Excel; +import com.zzyl.common.core.domain.BaseEntity; + +/** + * 入住表对象 check_in + * + * @author Zhy + * @date 2025-02-25 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel("入住表实体") +public class CheckIn extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + // 主键ID + @ApiModelProperty("主键ID") + private Long id; + + // 老人姓名 + @Excel(name = "老人姓名") + @ApiModelProperty("老人姓名") + private String elderName; + + // 老人ID + @Excel(name = "老人ID") + @ApiModelProperty("老人ID") + private Long elderId; + + // 身份证号 + @Excel(name = "身份证号") + @ApiModelProperty("身份证号") + private String idCardNo; + + // 入住开始时间 + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "入住开始时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty("入住开始时间") + private LocalDateTime startDate; + + // 入住结束时间 + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "入住结束时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty("入住结束时间") + private LocalDateTime endDate; + + // 护理等级名称 + @Excel(name = "护理等级名称") + @ApiModelProperty("护理等级名称") + private String nursingLevelName; + + // 入住床位 + @Excel(name = "入住床位") + @ApiModelProperty("入住床位") + private String bedNumber; + + // 状态 (0: 已入住, 1: 已退住) + @Excel(name = "状态 (0: 已入住, 1: 已退住)") + @ApiModelProperty("状态 (0: 已入住, 1: 已退住)") + private Integer status; + + // 排序编号 + @Excel(name = "排序编号") + @ApiModelProperty("排序编号") + private Integer sortOrder; + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/CheckInConfig.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/CheckInConfig.java new file mode 100644 index 0000000..08ab174 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/CheckInConfig.java @@ -0,0 +1,94 @@ +package com.zzyl.nursing.domain; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.AllArgsConstructor; +import com.zzyl.common.annotation.Excel; +import com.zzyl.common.core.domain.BaseEntity; + +/** + * 入住配置表对象 check_in_config + * + * @author Zhy + * @date 2025-02-25 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel("入住配置表实体") +public class CheckInConfig extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + // 主键ID + @ApiModelProperty("主键ID") + private Long id; + + // 入住表ID + @Excel(name = "入住表ID") + @ApiModelProperty("入住表ID") + private Long checkInId; + + // 护理等级ID + @Excel(name = "护理等级ID") + @ApiModelProperty("护理等级ID") + private Long nursingLevelId; + + // 护理等级名称 + @Excel(name = "护理等级名称") + @ApiModelProperty("护理等级名称") + private String nursingLevelName; + + // 费用开始时间 + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "费用开始时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty("费用开始时间") + private LocalDateTime feeStartDate; + + // 费用结束时间 + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "费用结束时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty("费用结束时间") + private LocalDateTime feeEndDate; + + // 押金(元) + @Excel(name = "押金", readConverterExp = "元=") + @ApiModelProperty("押金(元)") + private BigDecimal deposit; + + // 护理费用(元/月) + @Excel(name = "护理费用", readConverterExp = "元=/月") + @ApiModelProperty("护理费用(元/月)") + private BigDecimal nursingFee; + + // 床位费用(元/月) + @Excel(name = "床位费用", readConverterExp = "元=/月") + @ApiModelProperty("床位费用(元/月)") + private BigDecimal bedFee; + + // 医保支付(元/月) + @Excel(name = "医保支付", readConverterExp = "元=/月") + @ApiModelProperty("医保支付(元/月)") + private BigDecimal insurancePayment; + + // 政府补贴(元/月) + @Excel(name = "政府补贴", readConverterExp = "元=/月") + @ApiModelProperty("政府补贴(元/月)") + private BigDecimal governmentSubsidy; + + // 其他费用(元/月) + @Excel(name = "其他费用", readConverterExp = "元=/月") + @ApiModelProperty("其他费用(元/月)") + private BigDecimal otherFees; + + // 排序编号 + @Excel(name = "排序编号") + @ApiModelProperty("排序编号") + private Integer sortOrder; + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/Contract.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/Contract.java new file mode 100644 index 0000000..543206d --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/Contract.java @@ -0,0 +1,110 @@ +package com.zzyl.nursing.domain; + +import java.time.LocalDateTime; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.AllArgsConstructor; +import com.zzyl.common.annotation.Excel; +import com.zzyl.common.core.domain.BaseEntity; + +/** + * 合同表对象 contract + * + * @author Zhy + * @date 2025-02-25 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel("合同表实体") +public class Contract extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + // 主键ID + @ApiModelProperty("主键ID") + private Integer id; + + // 老人ID + @Excel(name = "老人ID") + @ApiModelProperty("老人ID") + private Integer elderId; + + // 合同名称 + @Excel(name = "合同名称") + @ApiModelProperty("合同名称") + private String contractName; + + // 合同编号 + @Excel(name = "合同编号") + @ApiModelProperty("合同编号") + private String contractNumber; + + // 协议地址(文件路径或URL) + @Excel(name = "协议地址", readConverterExp = "文=件路径或URL") + @ApiModelProperty("协议地址(文件路径或URL)") + private String agreementPath; + + // 丙方手机号 + @Excel(name = "丙方手机号") + @ApiModelProperty("丙方手机号") + private String thirdPartyPhone; + + // 丙方姓名 + @Excel(name = "丙方姓名") + @ApiModelProperty("丙方姓名") + private String thirdPartyName; + + // 老人姓名 + @Excel(name = "老人姓名") + @ApiModelProperty("老人姓名") + private String elderName; + + // 开始时间 + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "开始时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty("开始时间") + private LocalDateTime startDate; + + // 结束时间 + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "结束时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty("结束时间") + private LocalDateTime endDate; + + // 状态 (0: 未生效, 1: 已生效, 2: 已过期, 3: 已失效) + @Excel(name = "状态 (0: 未生效, 1: 已生效, 2: 已过期, 3: 已失效)") + @ApiModelProperty("状态 (0: 未生效, 1: 已生效, 2: 已过期, 3: 已失效)") + private Integer status; + + // 签约日期 + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "签约日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty("签约日期") + private LocalDateTime signDate; + + // 解除提交人 + @Excel(name = "解除提交人") + @ApiModelProperty("解除提交人") + private String terminationSubmitter; + + // 解除日期 + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "解除日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty("解除日期") + private LocalDateTime terminationDate; + + // 解除协议地址(文件路径或URL) + @Excel(name = "解除协议地址", readConverterExp = "文=件路径或URL") + @ApiModelProperty("解除协议地址(文件路径或URL)") + private String terminationAgreementPath; + + // 排序编号 + @Excel(name = "排序编号") + @ApiModelProperty("排序编号") + private Integer sortOrder; + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/Device.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/Device.java new file mode 100644 index 0000000..57410b6 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/Device.java @@ -0,0 +1,84 @@ +package com.zzyl.nursing.domain; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.AllArgsConstructor; +import com.zzyl.common.annotation.Excel; +import com.zzyl.common.core.domain.BaseEntity; + +/** + * 设备对象 device + * + * @author Zhy + * @date 2025-03-06 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel("设备实体") +public class Device extends BaseEntity { + + private static final long serialVersionUID = 1L; + + // 主键ID + @ApiModelProperty("主键ID") + private Long id; + + // 物联网设备ID + @Excel(name = "物联网设备ID") + @ApiModelProperty("物联网设备ID") + private String iotId; + + // 设备秘钥 + @Excel(name = "设备秘钥") + @ApiModelProperty("设备秘钥") + private String secret; + + // 绑定位置 + @Excel(name = "绑定位置") + @ApiModelProperty("绑定位置") + private String bindingLocation; + + // 位置类型 0:随身设备 1:固定设备 + @Excel(name = "位置类型 0:随身设备 1:固定设备") + @ApiModelProperty("位置类型 0:随身设备 1:固定设备") + private Integer locationType; + + // 物理位置类型 + @Excel(name = "物理位置类型") + @ApiModelProperty("物理位置类型") + private Integer physicalLocationType; + + // 设备名称 + @Excel(name = "设备名称") + @ApiModelProperty("设备名称") + private String deviceName; + + // 产品key + @Excel(name = "产品key") + @ApiModelProperty("产品key") + private String productKey; + + // 产品名称 + @Excel(name = "产品名称") + @ApiModelProperty("产品名称") + private String productName; + + // 位置备注 + @Excel(name = "位置备注") + @ApiModelProperty("位置备注") + private String deviceDescription; + + // 产品是否包含门禁 + @Excel(name = "产品是否包含门禁") + @ApiModelProperty("产品是否包含门禁") + private Integer haveEntranceGuard; + + // 节点id + @Excel(name = "节点id") + @ApiModelProperty("节点id") + private String nodeId; + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/DeviceData.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/DeviceData.java new file mode 100644 index 0000000..6083650 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/DeviceData.java @@ -0,0 +1,87 @@ +package com.zzyl.nursing.domain; + +import java.time.LocalDateTime; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.*; +import com.zzyl.common.annotation.Excel; +import com.zzyl.common.core.domain.BaseEntity; + +/** + * 设备数据对象 device_data + * + * @author Zhy + * @date 2025-03-08 + */ +@Data +@Getter +@Builder +@ToString +@EqualsAndHashCode(callSuper = false) +@ApiModel("设备数据实体") +public class DeviceData extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + // 告警规则ID,自增主键 + @ApiModelProperty("告警规则ID,自增主键") + private Long id; + + // 设备名称 + @Excel(name = "设备名称") + @ApiModelProperty("设备名称") + private String deviceName; + + // 设备ID + @Excel(name = "设备ID") + @ApiModelProperty("设备ID") + private String iotId; + + // 所属产品的key + @Excel(name = "所属产品的key") + @ApiModelProperty("所属产品的key") + private String productKey; + + // 产品名称 + @Excel(name = "产品名称") + @ApiModelProperty("产品名称") + private String productName; + + // 功能名称 + @Excel(name = "功能名称") + @ApiModelProperty("功能名称") + private String functionId; + + // 接入位置 + @Excel(name = "接入位置") + @ApiModelProperty("接入位置") + private String accessLocation; + + // 位置类型 0:随身设备 1:固定设备 + @Excel(name = "位置类型 0:随身设备 1:固定设备") + @ApiModelProperty("位置类型 0:随身设备 1:固定设备") + private Integer locationType; + + // 物理位置类型 0楼层 1房间 2床位 + @Excel(name = "物理位置类型 0楼层 1房间 2床位") + @ApiModelProperty("物理位置类型 0楼层 1房间 2床位") + private Integer physicalLocationType; + + // 位置备注 + @Excel(name = "位置备注") + @ApiModelProperty("位置备注") + private String deviceDescription; + + // 数据值 + @Excel(name = "数据值") + @ApiModelProperty("数据值") + private String dataValue; + + // 数据上报时间 + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "数据上报时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty("数据上报时间") + private LocalDateTime alarmTime; + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/DevicePropertyList.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/DevicePropertyList.java new file mode 100644 index 0000000..940457f --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/DevicePropertyList.java @@ -0,0 +1,20 @@ +package com.zzyl.nursing.domain; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.List; + +/** + * @author Chihiro + * @date 2025-03-14 12:00 + * @version v1.0 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class DevicePropertyList implements Serializable { + private List propertyStatusInfo; +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/Elder.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/Elder.java new file mode 100644 index 0000000..520fc40 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/Elder.java @@ -0,0 +1,89 @@ +package com.zzyl.nursing.domain; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.AllArgsConstructor; +import com.zzyl.common.annotation.Excel; +import com.zzyl.common.core.domain.BaseEntity; + +/** + * 老人对象 elder + * + * @author Zhy + * @date 2025-02-25 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel("老人实体") +public class Elder extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + // id + @ApiModelProperty("id") + private Long id; + + // 名称 + @Excel(name = "名称") + @ApiModelProperty("名称") + private String name; + + // 图片 + @Excel(name = "图片") + @ApiModelProperty("图片") + private String image; + + // 身份证号 + @Excel(name = "身份证号") + @ApiModelProperty("身份证号") + private String idCardNo; + + // 性别(0:女 1:男) + @Excel(name = "性别", readConverterExp = "0=:女,1=:男") + @ApiModelProperty("性别(0:女 1:男)") + private Integer sex; + + // 状态(0:禁用,1:启用 2:请假 3:退住中 4入住中 5已退住) + @Excel(name = "状态", readConverterExp = "0=:禁用,1:启用,2=:请假,3=:退住中,4=入住中,5=已退住") + @ApiModelProperty("状态(0:禁用,1:启用 2:请假 3:退住中 4入住中 5已退住)") + private Integer status; + + // 手机号 + @Excel(name = "手机号") + @ApiModelProperty("手机号") + private String phone; + + // 出生日期 + @Excel(name = "出生日期") + @ApiModelProperty("出生日期") + private String birthday; + + // 家庭住址 + @Excel(name = "家庭住址") + @ApiModelProperty("家庭住址") + private String address; + + // 身份证国徽面 + @Excel(name = "身份证国徽面") + @ApiModelProperty("身份证国徽面") + private String idCardNationalEmblemImg; + + // 身份证人像面 + @Excel(name = "身份证人像面") + @ApiModelProperty("身份证人像面") + private String idCardPortraitImg; + + // 床位编号 + @Excel(name = "床位编号") + @ApiModelProperty("床位编号") + private String bedNumber; + + // 床位id + @Excel(name = "床位id") + @ApiModelProperty("床位id") + private Long bedId; + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/FamilyMember.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/FamilyMember.java new file mode 100644 index 0000000..4536025 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/FamilyMember.java @@ -0,0 +1,54 @@ +package com.zzyl.nursing.domain; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.AllArgsConstructor; +import com.zzyl.common.annotation.Excel; +import com.zzyl.common.core.domain.BaseEntity; + +/** + * 老人家属对象 family_member + * + * @author Zhy + * @date 2025-03-03 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel("老人家属实体") +public class FamilyMember extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + // 主键 + @ApiModelProperty("主键") + private Long id; + + // 手机号 + @Excel(name = "手机号") + @ApiModelProperty("手机号") + private String phone; + + // 名称 + @Excel(name = "名称") + @ApiModelProperty("名称") + private String name; + + // 头像 + @Excel(name = "头像") + @ApiModelProperty("头像") + private String avatar; + + // OpenID + @Excel(name = "OpenID") + @ApiModelProperty("OpenID") + private String openId; + + // 性别(0:男,1:女) + @Excel(name = "性别(0:男,1:女)") + @ApiModelProperty("性别(0:男,1:女)") + private Integer gender; + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/FamilyMemberElder.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/FamilyMemberElder.java new file mode 100644 index 0000000..7918ff6 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/FamilyMemberElder.java @@ -0,0 +1,22 @@ +package com.zzyl.nursing.domain; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * @author Chihiro + * @date 2025-03-14 09:44 + * @version v1.0 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class FamilyMemberElder implements Serializable { + private Long id; + private Long familyMemberId; + private Long elderId; + private String elderName; +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/Floor.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/Floor.java new file mode 100644 index 0000000..91c7835 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/Floor.java @@ -0,0 +1,35 @@ +package com.zzyl.nursing.domain; + +import com.zzyl.common.annotation.Excel; +import com.zzyl.common.core.domain.BaseEntity; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 楼层对象 floor + * + * @author ruoyi + * @date 2024-04-26 + */ +@Data +@ApiModel("楼层实体") +public class Floor extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** id */ + @ApiModelProperty(value = "id") + private Long id; + + /** 名称 */ + @Excel(name = "名称") + @ApiModelProperty(value = "名称") + private String name; + + /** 编号 */ + @Excel(name = "编号") + @ApiModelProperty(value = "编号") + private Long code; + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/HealthAssessment.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/HealthAssessment.java new file mode 100644 index 0000000..65683b2 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/HealthAssessment.java @@ -0,0 +1,127 @@ +package com.zzyl.nursing.domain; + +import java.time.LocalDateTime; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.AllArgsConstructor; +import com.zzyl.common.annotation.Excel; +import com.zzyl.common.core.domain.BaseEntity; + +/** + * 健康评估对象 health_assessment + * + * @author Zhy + * @date 2025-02-28 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel("健康评估实体") +public class HealthAssessment extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + // 主键 + @ApiModelProperty("主键") + @TableId(type = IdType.AUTO, value = "id") + private Long id; + + // 老人姓名 + @Excel(name = "老人姓名") + @ApiModelProperty("老人姓名") + private String elderName; + + // 身份证号 + @Excel(name = "身份证号") + @ApiModelProperty("身份证号") + private String idCard; + + // 出生日期 + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "出生日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty("出生日期") + private LocalDateTime birthDate; + + // 年龄 + @Excel(name = "年龄") + @ApiModelProperty("年龄") + private Integer age; + + // 性别(0:男,1:女) + @Excel(name = "性别(0:男,1:女)") + @ApiModelProperty("性别(0:男,1:女)") + private Integer gender; + + // 健康评分 + @Excel(name = "健康评分") + @ApiModelProperty("健康评分") + private String healthScore; + + // 危险等级(健康, 提示, 风险, 危险, 严重危险) + @Excel(name = "危险等级(健康, 提示, 风险, 危险, 严重危险)") + @ApiModelProperty("危险等级(健康, 提示, 风险, 危险, 严重危险)") + private String riskLevel; + + // 是否建议入住(0:建议,1:不建议) + @Excel(name = "是否建议入住(0:建议,1:不建议)") + @ApiModelProperty("是否建议入住(0:建议,1:不建议)") + private Integer suggestionForAdmission; + + // 推荐护理等级 + @Excel(name = "推荐护理等级") + @ApiModelProperty("推荐护理等级") + private String nursingLevelName; + + // 入住情况(0:已入住,1:未入住) + @Excel(name = "入住情况(0:已入住,1:未入住)") + @ApiModelProperty("入住情况(0:已入住,1:未入住)") + private Integer admissionStatus; + + // 总检日期 + @Excel(name = "总检日期") + @ApiModelProperty("总检日期") + private String totalCheckDate; + + // 体检机构 + @Excel(name = "体检机构") + @ApiModelProperty("体检机构") + private String physicalExamInstitution; + + // 体检报告URL链接 + @Excel(name = "体检报告URL链接") + @ApiModelProperty("体检报告URL链接") + private String physicalReportUrl; + + // 评估时间 + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "评估时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty("评估时间") + private LocalDateTime assessmentTime; + + // 报告总结 + @Excel(name = "报告总结") + @ApiModelProperty("报告总结") + private String reportSummary; + + // 疾病风险 + @Excel(name = "疾病风险") + @ApiModelProperty("疾病风险") + private String diseaseRisk; + + // 异常分析 + @Excel(name = "异常分析") + @ApiModelProperty("异常分析") + private String abnormalAnalysis; + + // 健康系统分值 + @Excel(name = "健康系统分值") + @ApiModelProperty("健康系统分值") + private String systemScore; + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/MemberReservation.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/MemberReservation.java new file mode 100644 index 0000000..510c009 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/MemberReservation.java @@ -0,0 +1,65 @@ +package com.zzyl.nursing.domain; + +import java.time.LocalDateTime; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.AllArgsConstructor; +import com.zzyl.common.annotation.Excel; +import com.zzyl.common.core.domain.BaseEntity; + +/** + * 预约信息对象 reservation + * + * @author Zhy + * @date 2025-03-05 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel("预约信息实体") +@TableName("reservation") +public class MemberReservation extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + // 主键ID + @ApiModelProperty("主键ID") + private Long id; + + // 预约人姓名 + @Excel(name = "预约人姓名") + @ApiModelProperty("预约人姓名") + private String name; + + // 预约人手机号 + @Excel(name = "预约人手机号") + @ApiModelProperty("预约人手机号") + private String mobile; + + // 预约时间 + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "预约时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty("预约时间") + private LocalDateTime time; + + // 探访人 + @Excel(name = "探访人") + @ApiModelProperty("探访人") + private String visitor; + + // 预约类型,0:参观预约,1:探访预约 + @Excel(name = "预约类型,0:参观预约,1:探访预约") + @ApiModelProperty("预约类型,0:参观预约,1:探访预约") + private Integer type; + + // 预约状态,0:待报道,1:已完成,2:取消,3:过期 + @Excel(name = "预约状态,0:待报道,1:已完成,2:取消,3:过期") + @ApiModelProperty("预约状态,0:待报道,1:已完成,2:取消,3:过期") + private Integer status; + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/NursingElder.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/NursingElder.java new file mode 100644 index 0000000..06f9f0d --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/NursingElder.java @@ -0,0 +1,28 @@ +package com.zzyl.nursing.domain; + +import com.zzyl.common.annotation.Excel; +import com.zzyl.common.core.domain.BaseEntity; +import lombok.Data; + +/** + * 护理员老人关联对象 nursing_elder + * + * @author ruoyi + * @date 2024-05-28 + */ +@Data +public class NursingElder extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** id */ + private Long id; + + /** 护理员id */ + @Excel(name = "护理员id") + private Long nursingId; + + /** 老人id */ + @Excel(name = "老人id") + private Long elderId; +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/NursingLevel.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/NursingLevel.java new file mode 100644 index 0000000..21275cb --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/NursingLevel.java @@ -0,0 +1,55 @@ +package com.zzyl.nursing.domain; + +import java.math.BigDecimal; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.AllArgsConstructor; +import com.zzyl.common.annotation.Excel; +import com.zzyl.common.core.domain.BaseEntity; + +/** + * 护理等级对象 nursing_level + * + * @author alexis + * @date 2024-12-30 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel("护理等级实体") +public class NursingLevel extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + // 主键ID + @ApiModelProperty("主键ID") + private Long id; + + // 等级名称 + @Excel(name = "等级名称") + @ApiModelProperty("等级名称") + private String name; + + // 护理计划ID + @Excel(name = "护理计划ID") + @ApiModelProperty("护理计划ID") + private Long lplanId; + + // 护理费用 + @Excel(name = "护理费用") + @ApiModelProperty("护理费用") + private BigDecimal fee; + + // 状态(0:禁用,1:启用) + @Excel(name = "状态", readConverterExp = "0=:禁用,1:启用") + @ApiModelProperty("状态(0:禁用,1:启用)") + private Integer status; + + // 等级说明 + @Excel(name = "等级说明") + @ApiModelProperty("等级说明") + private String description; + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/NursingPlan.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/NursingPlan.java new file mode 100644 index 0000000..0355946 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/NursingPlan.java @@ -0,0 +1,44 @@ +package com.zzyl.nursing.domain; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.AllArgsConstructor; +import com.zzyl.common.annotation.Excel; +import com.zzyl.common.core.domain.BaseEntity; + +/** + * 护理计划对象 nursing_plan + * + * @author alexis + * @date 2024-12-30 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel("护理计划实体") +public class NursingPlan extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + // 编号 + @ApiModelProperty("编号") + private Long id; + + // 排序号 + @Excel(name = "排序号") + @ApiModelProperty("排序号") + private Integer sortNo; + + // 名称 + @Excel(name = "名称") + @ApiModelProperty("名称") + private String planName; + + // 状态 0禁用 1启用 + @Excel(name = "状态 0禁用 1启用") + @ApiModelProperty("状态 0禁用 1启用") + private Integer status; + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/NursingProject.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/NursingProject.java new file mode 100644 index 0000000..9708a18 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/NursingProject.java @@ -0,0 +1,65 @@ +package com.zzyl.nursing.domain; + +import java.math.BigDecimal; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.AllArgsConstructor; +import com.zzyl.common.annotation.Excel; +import com.zzyl.common.core.domain.BaseEntity; + +/** + * 护理项目对象 nursing_project + * + * @author alexis + * @date 2024-12-30 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel("护理项目实体") +public class NursingProject extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + // 编号 + @ApiModelProperty("编号") + private Long id; + + // 名称 + @Excel(name = "名称") + @ApiModelProperty("名称") + private String name; + + // 排序号 + @Excel(name = "排序号") + @ApiModelProperty("排序号") + private Integer orderNo; + + // 单位 + @Excel(name = "单位") + @ApiModelProperty("单位") + private String unit; + + // 价格 + @Excel(name = "价格") + @ApiModelProperty("价格") + private BigDecimal price; + + // 图片 + @Excel(name = "图片") + @ApiModelProperty("图片") + private String image; + + // 护理要求 + @Excel(name = "护理要求") + @ApiModelProperty("护理要求") + private String nursingRequirement; + + // 状态(0:禁用,1:启用) + @Excel(name = "状态", readConverterExp = "0=:禁用,1:启用") + @ApiModelProperty("状态(0:禁用,1:启用)") + private Integer status; + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/NursingProjectPlan.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/NursingProjectPlan.java new file mode 100644 index 0000000..37569f3 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/NursingProjectPlan.java @@ -0,0 +1,54 @@ +package com.zzyl.nursing.domain; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.AllArgsConstructor; +import com.zzyl.common.annotation.Excel; +import com.zzyl.common.core.domain.BaseEntity; + +/** + * 护理计划和项目关联对象 nursing_project_plan + * + * @author alexis + * @date 2024-12-31 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel("护理计划和项目关联实体") +public class NursingProjectPlan extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + // 主键id + @ApiModelProperty("主键id") + private Long id; + + // 计划id + @Excel(name = "计划id") + @ApiModelProperty("计划id") + private Long planId; + + // 项目id + @Excel(name = "项目id") + @ApiModelProperty("项目id") + private Long projectId; + + // 计划执行时间 + @Excel(name = "计划执行时间") + @ApiModelProperty("计划执行时间") + private String executeTime; + + // 执行周期 0 天 1 周 2月 + @Excel(name = "执行周期 0 天 1 周 2月") + @ApiModelProperty("执行周期 0 天 1 周 2月") + private Integer executeCycle; + + // 执行频次 + @Excel(name = "执行频次") + @ApiModelProperty("执行频次") + private Integer executeFrequency; + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/NursingTask.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/NursingTask.java new file mode 100644 index 0000000..9da514c --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/NursingTask.java @@ -0,0 +1,101 @@ +package com.zzyl.nursing.domain; + +import java.time.LocalDateTime; +import java.util.List; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.AllArgsConstructor; +import com.zzyl.common.annotation.Excel; +import com.zzyl.common.core.domain.BaseEntity; + +/** + * 护理任务对象 nursing_task + * + * @author zzyl + * @date 2025-03-14 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel("护理任务实体") +public class NursingTask extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + // id + @ApiModelProperty("id") + private Long id; + + // 护理员id + @Excel(name = "护理员id") + @ApiModelProperty("护理员id") + private String nursingId; + + // 项目id + @Excel(name = "项目id") + @ApiModelProperty("项目id") + private Integer projectId; + + // 护理项目名称 + @Excel(name = "护理项目名称") + @ApiModelProperty("护理项目名称") + private String projectName; + + // 老人id + @Excel(name = "老人id") + @ApiModelProperty("老人id") + private Long elderId; + + // 老人姓名 + @Excel(name = "老人姓名") + @ApiModelProperty("老人姓名") + private String elderName; + + // 床位编号 + @Excel(name = "床位编号") + @ApiModelProperty("床位编号") + private String bedNumber; + + // 预计服务时间 + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "预计服务时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty("预计服务时间") + private LocalDateTime estimatedServerTime; + + // 实际服务时间 + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "实际服务时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty("实际服务时间") + private LocalDateTime realServerTime; + + // 执行记录 + @Excel(name = "执行记录") + @ApiModelProperty("执行记录") + private String mark; + + // 取消原因 + @Excel(name = "取消原因") + @ApiModelProperty("取消原因") + private String cancelReason; + + // 状态 1待执行 2已执行 3已关闭 + @Excel(name = "状态 1待执行 2已执行 3已关闭 ") + @ApiModelProperty("状态 1待执行 2已执行 3已关闭 ") + private Integer status; + + // 执行图片 + @Excel(name = "执行图片") + @ApiModelProperty("执行图片") + private String taskImage; + + // 任务类型 1护理计划外 2护理计划内 + @Excel(name = "任务类型 1护理计划外 2护理计划内") + @ApiModelProperty("任务类型 1护理计划外 2护理计划内") + private String taskType; + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/PropertyStatusInfo.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/PropertyStatusInfo.java new file mode 100644 index 0000000..97e8746 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/PropertyStatusInfo.java @@ -0,0 +1,24 @@ +package com.zzyl.nursing.domain; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * @author Chihiro + * @date 2025-03-14 12:06 + * @version v1.0 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class PropertyStatusInfo implements Serializable { + private String dataType; + private String identifier; + private String name; + private Long time; + private String unit; + private double value; +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/Room.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/Room.java new file mode 100644 index 0000000..27516b4 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/Room.java @@ -0,0 +1,51 @@ +package com.zzyl.nursing.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.zzyl.common.annotation.Excel; +import com.zzyl.common.core.domain.BaseEntity; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 房间对象 room + * + * @author ruoyi + * @date 2024-04-26 + */ +@Data +@ApiModel("房间实体对象") +public class Room extends BaseEntity { + private static final long serialVersionUID = 1L; + + /** 主键ID */ + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** 房间编号 */ + @ApiModelProperty(value = "房间编号") + @Excel(name = "房间编号") + private String code; + + /** 排序号 */ + @ApiModelProperty(value = "排序号") + @Excel(name = "排序号") + private Long sort; + + /** 房间类型名称 */ + @ApiModelProperty(value = "房间类型名称") + @Excel(name = "房间类型名称") + private String typeName; + + /** 楼层id */ + @ApiModelProperty(value = "楼层id") + @Excel(name = "楼层id") + private Long floorId; + + /** 是否删除 */ + @ApiModelProperty(value = "是否删除") + @Excel(name = "是否删除") + private Integer isDeleted; + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/RoomType.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/RoomType.java new file mode 100644 index 0000000..084d1ac --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/domain/RoomType.java @@ -0,0 +1,47 @@ +package com.zzyl.nursing.domain; + +import com.zzyl.common.annotation.Excel; +import com.zzyl.common.core.domain.BaseEntity; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 房型对象 room_type + * + * @author ruoyi + * @date 2024-04-26 + */ +@Data +public class RoomType extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键ID */ + private Long id; + + /** 房型名称 */ + @Excel(name = "房型名称") + private String name; + + /** 床位数量 */ + @Excel(name = "床位数量") + private Long bedCount; + + /** 床位费用 */ + @Excel(name = "床位费用") + private BigDecimal price; + + /** 介绍 */ + @Excel(name = "介绍") + private String introduction; + + /** 照片 */ + @Excel(name = "照片") + private String photo; + + /** 状态,0:禁用,1:启用 */ + @Excel(name = "状态,0:禁用,1:启用") + private Long status; + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/AlertDataPageQueryDto.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/AlertDataPageQueryDto.java new file mode 100644 index 0000000..9e63ea2 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/AlertDataPageQueryDto.java @@ -0,0 +1,38 @@ +package com.zzyl.nursing.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.Date; + +/** + * 分页查询警告数据dto + * + * @author Zhy + * @version 1.0 + * @date 2025-03-12 17:35 + */ +@Data +@ApiModel(value = "分页查询警告数据dto") +public class AlertDataPageQueryDto { + + @ApiModelProperty(value = "页码") + private Integer pageNum; + + @ApiModelProperty(value = "每页条数") + private Integer pageSize; + + @ApiModelProperty(value = "设备名称") + private String deviceName; + + @ApiModelProperty(value = "开始报警时间") + private Date startTime; + + @ApiModelProperty(value = "结束报警时间") + private Date endTime; + + @ApiModelProperty(value = "状态") + private Integer status; + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/CheckInApplyDto.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/CheckInApplyDto.java new file mode 100644 index 0000000..9b25845 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/CheckInApplyDto.java @@ -0,0 +1,42 @@ +package com.zzyl.nursing.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +/** + * 申请入住请求DTO + * + * @Author: Zhy + * @Date: 2025-02-25 + **/ +@ApiModel(description = "申请入住请求模型") +@Data +public class CheckInApplyDto { + + /** + * 老人信息 + */ + @ApiModelProperty(value = "老人信息") + private CheckInElderDto checkInElderDto; + + /** + * 家属信息 + */ + @ApiModelProperty(value = "家属信息") + private List elderFamilyDtoList; + + /** + * 入住配置 + */ + @ApiModelProperty(value = "入住配置") + private CheckInConfigDto checkInConfigDto; + + /** + * 签约办理 + */ + @ApiModelProperty(value = "签约办理") + private CheckInContractDto checkInContractDto; +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/CheckInConfigDto.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/CheckInConfigDto.java new file mode 100644 index 0000000..432cc0f --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/CheckInConfigDto.java @@ -0,0 +1,76 @@ +package com.zzyl.nursing.dto; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + * 入住配置信息 + * + * @Author: Zhy + * @Date: 2025-02-25 + */ +@ApiModel(description = "入住配置信息") +@Data +public class CheckInConfigDto { + + @ApiModelProperty(value = "入住开始时间,格式:yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime startDate; + + @ApiModelProperty(value = "入住结束时间,格式:yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime endDate; + + @ApiModelProperty(value = "费用开始时间,格式:yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime feeStartDate; + + @ApiModelProperty(value = "费用结束时间,格式:yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime feeEndDate; + + @ApiModelProperty(value = "护理等级ID") + private Long nursingLevelId; + + @ApiModelProperty(value = "护理等级名称") + private String nursingLevelName; + + @ApiModelProperty(value = "床位Id") + private Long bedId; + + @ApiModelProperty(value = "押金金额") + private BigDecimal deposit; + + @ApiModelProperty(value = "护理费用") + private BigDecimal nursingFee; + + @ApiModelProperty(value = "床位费用") + private BigDecimal bedFee; + + @ApiModelProperty(value = "其他费用") + private BigDecimal otherFees; + + @ApiModelProperty(value = "医保支付") + private BigDecimal insurancePayment; + + @ApiModelProperty(value = "政府补贴") + private BigDecimal governmentSubsidy; + + @ApiModelProperty("房间ID") + private Long roomId; + + @ApiModelProperty(value = "楼层id") + private Long floorId; + + @ApiModelProperty(value = "楼层名称") + private String floorName; + + @ApiModelProperty(value = "房间编号") + private String code; + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/CheckInContractDto.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/CheckInContractDto.java new file mode 100644 index 0000000..18c6a50 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/CheckInContractDto.java @@ -0,0 +1,53 @@ + +package com.zzyl.nursing.dto; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 合同信息 + * + * @Author: Zhy + * @Date: 2025-02-25 + */ +@ApiModel(description = "合同信息") +@Data +public class CheckInContractDto { + /** + * 合同名称 + */ + @ApiModelProperty(value = "合同名称") + private String contractName; + + /** + * 签约时间 + */ + @ApiModelProperty(value = "签约时间,格式:yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime signDate; + + /** + * 丙方名称 + */ + @ApiModelProperty(value = "丙方名称") + private String thirdPartyName; + + /** + * 丙方手机号 + */ + @ApiModelProperty(value = "丙方手机号") + private String thirdPartyPhone; + + /** + * 合同pdf文件地址 + */ + @ApiModelProperty(value = "合同pdf文件地址") + private String agreementPath; + +} + + diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/CheckInElderDto.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/CheckInElderDto.java new file mode 100644 index 0000000..3027999 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/CheckInElderDto.java @@ -0,0 +1,75 @@ +package com.zzyl.nursing.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 老人入住请求模型 + * + * @Author: Zhy + * @Date: 2025-02-25 + **/ +@ApiModel(description = "老人入住请求模型") +@Data +public class CheckInElderDto { + /** + * 姓名 + */ + @ApiModelProperty(value = "姓名") + private String name; + + /** + * 身份证号 + */ + @ApiModelProperty(value = "身份证号") + private String idCardNo; + + /** + * 出生日期,格式:yyyy-MM-dd + */ + @ApiModelProperty(value = "出生日期,格式:yyyy-MM-dd") + private String birthday; + + /** + * 年龄 + */ + @ApiModelProperty(value = "年龄") + private Integer age; + + /** + * 性别,0:男,1:女,2:未知 + */ + @ApiModelProperty(value = "性别,0:男,1:女,2:未知") + private Integer sex; + + /** + * 手机号 + */ + @ApiModelProperty(value = "手机号") + private String phone; + + /** + * 家庭住址 + */ + @ApiModelProperty(value = "家庭住址") + private String address; + + /** + * 一寸照片 + */ + @ApiModelProperty(value = "一寸照片") + private String image; + + /** + * 身份证国徽面 + */ + @ApiModelProperty(value = "身份证国徽面") + private String idCardNationalEmblemImg; + + /** + * 身份证人像面 + */ + @ApiModelProperty(value = "身份证人像面") + private String idCardPortraitImg; +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/DeviceDataPageReqDto.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/DeviceDataPageReqDto.java new file mode 100644 index 0000000..ba4afc6 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/DeviceDataPageReqDto.java @@ -0,0 +1,41 @@ +package com.zzyl.nursing.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDateTime; + +/** + * 设备指定属性的数据分页查询 + * + * @author Zhy + * @version 1.0 + * @date 2025-03-08 16:26 + */ +@Data +@ApiModel("设备指定属性的数据分页查询") +public class DeviceDataPageReqDto { + + @ApiModelProperty(value = "设备名称", required = false) + private String deviceName; + + @ApiModelProperty(value = "功能ID", required = false) + private String functionId; + + @ApiModelProperty(value = "开始时间", required = false) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime startTime; + + @ApiModelProperty(value = "结束时间", required = false) + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime endTime; + + @ApiModelProperty(value = "页码", required = true, example = "1") + private Integer pageNum; + + @ApiModelProperty(value = "页面大小", required = true, example = "10") + private Integer pageSize; + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/DeviceDto.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/DeviceDto.java new file mode 100644 index 0000000..aea1489 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/DeviceDto.java @@ -0,0 +1,53 @@ +package com.zzyl.nursing.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 设备注册参数 + * + * @author Zhy + * @version 1.0 + * @date 2025-03-06 11:16 + */ +@Data +@ApiModel(value = "设备注册参数") +public class DeviceDto { + + private Long id; + + /** 备注 */ + private String remark; + + /** + * 设备标识码,通常使用IMEI、MAC地址或Serial No作为node_id + */ + @ApiModelProperty(value = "设备标识码", required = true) + private String nodeId; + + @ApiModelProperty(value = "设备id") + public String iotId; + + @ApiModelProperty(value = "产品的id") + public String productKey; + + @ApiModelProperty(value = "产品名称") + private String productName; + + @ApiModelProperty(value = "位置名称回显字段") + private String deviceDescription; + + @ApiModelProperty(value = "位置类型 0 老人 1位置") + Integer locationType; + + @ApiModelProperty(value = "绑定位置") + Long bindingLocation; + + @ApiModelProperty(value = "设备名称") + String deviceName; + + @ApiModelProperty(value = "物理位置类型 0楼层 1房间 2床位") + Integer physicalLocationType; + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/ElderDto.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/ElderDto.java new file mode 100644 index 0000000..c02cebc --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/ElderDto.java @@ -0,0 +1,25 @@ +package com.zzyl.nursing.dto; + +import com.zzyl.common.core.domain.BaseEntity; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * @author Chihiro + * @date 2025-03-14 09:46 + * @version v1.0 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class ElderDto extends BaseEntity implements Serializable { + private Long id; + private String idCard; + private String name; + private String remark; + private Long familyMemberId; + private Long elderId; +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/ElderFamilyDto.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/ElderFamilyDto.java new file mode 100644 index 0000000..2a79aa3 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/ElderFamilyDto.java @@ -0,0 +1,36 @@ +package com.zzyl.nursing.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 老人家属信息 + * + * @Author: Zhy + * @Date: 2025-02-25 + **/ +@ApiModel(description = "老人家属信息") +@Data +public class ElderFamilyDto { + + /** + * 姓名 + */ + @ApiModelProperty(value = "姓名") + private String name; + + + /** + * 联系方式 + */ + @ApiModelProperty(value = "联系方式") + private String phone; + + /** + * 亲属关系 + */ + @ApiModelProperty(value = "亲属关系") + private String kinship; + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/ElderPageQuery.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/ElderPageQuery.java new file mode 100644 index 0000000..0915b88 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/ElderPageQuery.java @@ -0,0 +1,42 @@ +package com.zzyl.nursing.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 分页查询老人信息 + * + * @author Zhy + * @version 1.0 + * @date 2025-03-06 10:53 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel(value = "分页查询老人信息") +public class ElderPageQuery { + + /** 状态 0-禁用 1-启用 */ + @ApiModelProperty(value = "状态 0-禁用 1-启用") + private Integer status; + + /** 页码 */ + @ApiModelProperty(value = "页码") + private Integer pageNum; + + /** 每页条数 */ + @ApiModelProperty(value = "每页条数") + private Integer pageSize; + + /** 姓名 */ + @ApiModelProperty(value = "姓名") + private String name; + + /** 身份证号 */ + @ApiModelProperty(value = "身份证号") + private String idCardNo; + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/HandleAlertDataDto.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/HandleAlertDataDto.java new file mode 100644 index 0000000..c187795 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/HandleAlertDataDto.java @@ -0,0 +1,29 @@ +package com.zzyl.nursing.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 处理设备报警数据DTO + * + * @author Zhy + * @version 1.0 + * @date 2025-03-12 18:02 + */ +@Data +@ApiModel(value = "处理设备报警数据DTO") +public class HandleAlertDataDto { + + @ApiModelProperty(value = "主键ID") + private Long id; + + @ApiModelProperty(value = "处理结果") + private String processingResult; + + @ApiModelProperty(value = "处理时间") + private LocalDateTime processingTime; + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/HealthAssessmentDto.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/HealthAssessmentDto.java new file mode 100644 index 0000000..2dc4604 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/HealthAssessmentDto.java @@ -0,0 +1,42 @@ +package com.zzyl.nursing.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 健康评估 + * + * @Author: Zhy + * @Date: 2025-02-28 16:39 + * @Version: 1.0 + */ +@Data +@ApiModel("健康评估") +public class HealthAssessmentDto { + + /** + * 老人姓名 + */ + @ApiModelProperty(value = "老人姓名", required = true) + private String elderName; + + /** + * 身份证号 + */ + @ApiModelProperty(value = "身份证号", required = true) + private String idCard; + + /** + * 体检机构 + */ + @ApiModelProperty(value = "体检机构", required = true) + private String physicalExamInstitution; + + /** + * 体检报告URL链接 + */ + @ApiModelProperty(value = "体检报告URL链接", required = true) + private String physicalReportUrl; + +} \ No newline at end of file diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/NursingElderDto.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/NursingElderDto.java new file mode 100644 index 0000000..a8aaef3 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/NursingElderDto.java @@ -0,0 +1,18 @@ +package com.zzyl.nursing.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +@Data +@ApiModel("护理员与老人关系Dto") +public class NursingElderDto { + + @ApiModelProperty(value = "老人id") + private Long elderId; + + @ApiModelProperty(value = "护理员id列表") + private List nursingIds; +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/NursingPlanDto.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/NursingPlanDto.java new file mode 100644 index 0000000..c8a5d75 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/NursingPlanDto.java @@ -0,0 +1,37 @@ +package com.zzyl.nursing.dto; + +import com.zzyl.nursing.domain.NursingProjectPlan; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +@Data +public class NursingPlanDto { + + + private Long id; + + /** + * 排序号 + */ + @ApiModelProperty(value = "排序号") + private Integer sortNo; + + /** + * 计划名称 + */ + @ApiModelProperty(value = "计划名称") + private String planName; + + /** + * 状态(0:禁用,1:启用) + */ + @ApiModelProperty(value = "状态(0:禁用,1:启用)") + private Integer status; + + /** + * 护理计划关联项目列表 + */ + List projectPlans; +} \ No newline at end of file diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/NursingTaskCancelDto.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/NursingTaskCancelDto.java new file mode 100644 index 0000000..0667dc0 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/NursingTaskCancelDto.java @@ -0,0 +1,20 @@ +package com.zzyl.nursing.dto; + +import io.swagger.annotations.ApiModel; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author shd + * @version V1.0 + * @date 2025-03-14 15:16 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel("护理任务取消原因") +public class NursingTaskCancelDto { + private String reason; + private Long taskId; +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/NursingTaskDoDto.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/NursingTaskDoDto.java new file mode 100644 index 0000000..798986a --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/NursingTaskDoDto.java @@ -0,0 +1,22 @@ +package com.zzyl.nursing.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +/** + * @author shd + * @version V1.0 + * @date 2025-03-14 15:28 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class NursingTaskDoDto { + private String estimatedServerTime; + private String mark; + private Long taskId; + private String taskImage; +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/NursingTaskDto.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/NursingTaskDto.java new file mode 100644 index 0000000..9aac0d4 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/NursingTaskDto.java @@ -0,0 +1,59 @@ +package com.zzyl.nursing.dto; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.zzyl.common.annotation.Excel; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * @author shd + * @version V1.0 + * @date 2025-03-14 14:31 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel("护理任务Dto") +public class NursingTaskDto { + private static final long serialVersionUID = 1L; + + // 护理员id + @Excel(name = "护理员id") + @ApiModelProperty("护理员id") + private String nurseId; + + // 项目id + @Excel(name = "项目id") + @ApiModelProperty("项目id") + private Integer projectId; + + // 老人姓名 + @Excel(name = "老人姓名") + @ApiModelProperty("老人姓名") + private String elderName; + + // 状态 1待执行 2已执行 3已关闭 + @Excel(name = "状态 1待执行 2已执行 3已关闭 ") + @ApiModelProperty("状态 1待执行 2已执行 3已关闭 ") + private Integer status; + + /** 页码 */ + @ApiModelProperty(value = "页码") + private Integer pageNum; + + /** 每页条数 */ + @ApiModelProperty(value = "每页条数") + private Integer pageSize; + + @ApiModelProperty(value = "结束时间") + private LocalDateTime endTime; + + @ApiModelProperty(value = "开始时间") + private LocalDateTime startTime; +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/NursingTaskUpdateDto.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/NursingTaskUpdateDto.java new file mode 100644 index 0000000..4b6039c --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/NursingTaskUpdateDto.java @@ -0,0 +1,20 @@ +package com.zzyl.nursing.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +/** + * @author shd + * @version V1.0 + * @date 2025-03-14 15:38 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class NursingTaskUpdateDto { + private String estimatedServerTime; + private Long taskId; +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/QueryDevicePropertyDto.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/QueryDevicePropertyDto.java new file mode 100644 index 0000000..6ff571e --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/QueryDevicePropertyDto.java @@ -0,0 +1,20 @@ +package com.zzyl.nursing.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * @author Chihiro + * @date 2025-03-14 11:56 + * @version v1.0 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class QueryDevicePropertyDto implements Serializable { + private String deviceName; + private String productKey; +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/UserLoginRequestDto.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/UserLoginRequestDto.java new file mode 100644 index 0000000..d20c505 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/dto/UserLoginRequestDto.java @@ -0,0 +1,25 @@ +package com.zzyl.nursing.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * C端用户登录 + * + * @author Zhy + * @version 1.0 + * @date 2025-03-03 16:14 + */ +@Data +public class UserLoginRequestDto { + + @ApiModelProperty("昵称") + private String nickName; + + @ApiModelProperty("登录临时凭证") + private String code; + + @ApiModelProperty("手机号临时凭证") + private String phoneCode; + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/job/AlertJob.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/job/AlertJob.java new file mode 100644 index 0000000..855b077 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/job/AlertJob.java @@ -0,0 +1,24 @@ +package com.zzyl.nursing.job; + +import com.zzyl.nursing.service.IAlertRuleService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +/** + * 设备数据告警过滤定时任务 + * + * @author Zhy + * @version 1.0 + * @date 2025-03-11 15:56 + */ +@Component +@RequiredArgsConstructor +public class AlertJob { + + private final IAlertRuleService alertRuleService; + + public void deviceDataAlertFilter() { + alertRuleService.alertFilter(); + } + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/job/AmqpClient.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/job/AmqpClient.java new file mode 100644 index 0000000..5a6890d --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/job/AmqpClient.java @@ -0,0 +1,270 @@ +package com.zzyl.nursing.job; + +import cn.hutool.core.text.CharSequenceUtil; +import cn.hutool.core.util.ObjUtil; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import com.zzyl.framework.config.properties.HuaWeiIotConfigProperties; +import com.zzyl.nursing.service.IDeviceDataService; +import com.zzyl.nursing.vo.IotMsgNotifyData; +import lombok.extern.slf4j.Slf4j; +import org.apache.qpid.jms.*; +import org.apache.qpid.jms.message.JmsInboundMessageDispatch; +import org.apache.qpid.jms.transports.TransportOptions; +import org.apache.qpid.jms.transports.TransportSupport; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import org.springframework.stereotype.Component; + +import javax.jms.*; +import java.net.InetAddress; +import java.net.URI; +import java.net.UnknownHostException; +import java.text.MessageFormat; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import java.util.stream.Collectors; + +/** + * @author itcast + */ +@Slf4j +@Component +public class AmqpClient implements ApplicationRunner { + + @Autowired + private HuaWeiIotConfigProperties huaWeiIotConfigProperties; + + @Autowired + private IDeviceDataService deviceDataService; + + // 业务处理异步线程池,线程池参数可以根据您的业务特点调整,或者您也可以用其他异步方式处理接收到的消息。 + @Autowired + @Qualifier("threadPoolTaskExecutor") + private ThreadPoolTaskExecutor threadPoolTaskExecutor; + + // 控制台服务端订阅中消费组状态页客户端ID一栏将显示clientId参数。 + // 建议使用机器UUID、MAC地址、IP等唯一标识等作为clientId。便于您区分识别不同的客户端。 + private static String clientId; + + static { + try { + clientId = InetAddress.getLocalHost().getHostAddress(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + } + + @Override + public void run(ApplicationArguments args) throws Exception { + start(); + } + + public void start() throws Exception { + // 参数说明,请参见AMQP客户端接入说明文档。 + for (int i = 0; i < huaWeiIotConfigProperties.getConnectionCount(); i++) { + // 创建amqp连接 + Connection connection = getConnection(); + + // 加入监听者 + ((JmsConnection) connection).addConnectionListener(myJmsConnectionListener); + // 创建会话。 + // Session.CLIENT_ACKNOWLEDGE: 收到消息后,需要手动调用message.acknowledge()。 + // Session.AUTO_ACKNOWLEDGE: SDK自动ACK(推荐)。 + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + connection.start(); + + // 创建Receiver连接。 + MessageConsumer consumer = newConsumer(session, connection, huaWeiIotConfigProperties.getQueueName()); + consumer.setMessageListener(messageListener); + } + + log.info("amqp is started successfully, and will exit after server shutdown "); + } + + /** + * 创建amqp连接 + * + * @return amqp连接 + */ + private Connection getConnection() throws Exception { + String connectionUrl = generateConnectUrl(); + JmsConnectionFactory cf = new JmsConnectionFactory(connectionUrl); + // 信任服务端 + TransportOptions to = new TransportOptions(); + to.setTrustAll(true); + cf.setSslContext(TransportSupport.createJdkSslContext(to)); + String userName = "accessKey=" + huaWeiIotConfigProperties.getAccessKey(); + cf.setExtension(JmsConnectionExtensions.USERNAME_OVERRIDE.toString(), (connection, uri) -> { + // IoTDA的userName组成格式如下:“accessKey=${accessKey}|timestamp=${timestamp}” + String newUserName = userName; + if (connection instanceof JmsConnection) { + newUserName = ((JmsConnection) connection).getUsername(); + } + return newUserName + "|timestamp=" + System.currentTimeMillis(); + }); + + // 创建连接。 + return cf.createConnection(userName, huaWeiIotConfigProperties.getAccessCode()); + } + + /** + * 生成amqp连接地址 + * + * @return amqp连接地址 + */ + public String generateConnectUrl() { + String uri = MessageFormat.format("{0}://{1}:{2}", + (huaWeiIotConfigProperties.isUseSsl() ? "amqps" : "amqp"), + huaWeiIotConfigProperties.getHost(), + String.valueOf(huaWeiIotConfigProperties.getPort()) + ); + Map uriOptions = new HashMap<>(); + uriOptions.put("amqp.vhost", huaWeiIotConfigProperties.getVhost()); + uriOptions.put("amqp.idleTimeout", String.valueOf(huaWeiIotConfigProperties.getIdleTimeout())); + uriOptions.put("amqp.saslMechanisms", huaWeiIotConfigProperties.getSaslMechanisms()); + + Map jmsOptions = new HashMap<>(); + jmsOptions.put("jms.prefetchPolicy.queuePrefetch", String.valueOf(huaWeiIotConfigProperties.getQueuePrefetch())); + if (CharSequenceUtil.isNotBlank(clientId)) { + jmsOptions.put("jms.clientID", clientId); + } else { + jmsOptions.put("jms.clientID", UUID.randomUUID().toString()); + } + jmsOptions.put("failover.reconnectDelay", String.valueOf(huaWeiIotConfigProperties.getReconnectDelay())); + jmsOptions.put("failover.maxReconnectDelay", String.valueOf(huaWeiIotConfigProperties.getMaxReconnectDelay())); + if (huaWeiIotConfigProperties.getMaxReconnectAttempts() > 0) { + jmsOptions.put("failover.maxReconnectAttempts", + String.valueOf(huaWeiIotConfigProperties.getMaxReconnectAttempts()) + ); + } + if (huaWeiIotConfigProperties.getExtendedOptions() != null) { + for (Map.Entry option : huaWeiIotConfigProperties.getExtendedOptions().entrySet()) { + if (option.getKey().startsWith("amqp.") || option.getKey().startsWith("transport.")) { + uriOptions.put(option.getKey(), option.getValue()); + } else { + jmsOptions.put(option.getKey(), option.getValue()); + } + } + } + return uriOptions.entrySet().stream().map(option -> MessageFormat.format("{0}={1}", + option.getKey(), + option.getValue() + )).collect(Collectors.joining("&", "failover:(" + uri + "?", ")")) + + jmsOptions.entrySet() + .stream() + .map(option -> MessageFormat.format("{0}={1}", option.getKey(), option.getValue())) + .collect(Collectors.joining("&", "?", "")); + } + + /** + * 创建消费者 + * + * @param session session + * @param connection amqp连接 + * @param queueName 队列名称 + * @return 消费者 + */ + public MessageConsumer newConsumer(Session session, Connection connection, String queueName) throws Exception { + if (!(connection instanceof JmsConnection) || ((JmsConnection) connection).isClosed()) { + throw new Exception("create consumer failed,the connection is disconnected."); + } + + return session.createConsumer(new JmsQueue(queueName)); + } + + private final MessageListener messageListener = message -> { + try { + // 异步处理收到的消息,确保onMessage函数里没有耗时逻辑 + threadPoolTaskExecutor.submit(() -> processMessage(message)); + } catch (Exception e) { + log.error("submit task occurs exception ", e); + } + }; + + /** + * 在这里处理您收到消息后的具体业务逻辑。 + */ + private void processMessage(Message message) { + String contentStr; + try { + contentStr = message.getBody(String.class); + String topic = message.getStringProperty("topic"); + String messageId = message.getStringProperty("messageId"); + log.warn("receive message,\n topic = {},\n messageId = {},\n content = {}", topic, messageId, contentStr); + + // 从消息内容中解析出业务数据 + JSONObject jsonObject = JSONUtil.parseObj(contentStr); + JSONObject notifyDataJson = jsonObject.getJSONObject("notify_data"); + if (ObjUtil.isEmpty(notifyDataJson)) { + return; + } + // 类型转换 + IotMsgNotifyData notifyData = JSONUtil.toBean(notifyDataJson, IotMsgNotifyData.class); + if (ObjUtil.isEmpty(notifyData) || + ObjUtil.isEmpty(notifyData.getHeader()) || + ObjUtil.isEmpty(notifyData.getBody())) { + return; + } + // 存入数据库 + deviceDataService.batchInsertDeviceData(notifyData); + } catch (JMSException e) { + throw new RuntimeException("服务器错误"); + } + + } + + private final JmsConnectionListener myJmsConnectionListener = new JmsConnectionListener() { + /** + * 连接成功建立。 + */ + @Override + public void onConnectionEstablished(URI remoteURI) { + log.info("onConnectionEstablished, remoteUri:{}", remoteURI); + } + + /** + * 尝试过最大重试次数之后,最终连接失败。 + */ + @Override + public void onConnectionFailure(Throwable error) { + log.error("onConnectionFailure, {}", error.getMessage()); + } + + /** + * 连接中断。 + */ + @Override + public void onConnectionInterrupted(URI remoteURI) { + log.info("onConnectionInterrupted, remoteUri:{}", remoteURI); + } + + /** + * 连接中断后又自动重连上。 + */ + @Override + public void onConnectionRestored(URI remoteURI) { + log.info("onConnectionRestored, remoteUri:{}", remoteURI); + } + + @Override + public void onInboundMessage(JmsInboundMessageDispatch envelope) { + } + + @Override + public void onSessionClosed(Session session, Throwable cause) { + } + + @Override + public void onConsumerClosed(MessageConsumer consumer, Throwable cause) { + } + + @Override + public void onProducerClosed(MessageProducer producer, Throwable cause) { + } + }; +} \ No newline at end of file diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/job/ContractJob.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/job/ContractJob.java new file mode 100644 index 0000000..01d5446 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/job/ContractJob.java @@ -0,0 +1,30 @@ +package com.zzyl.nursing.job; + +import com.zzyl.nursing.service.IContractService; +import com.zzyl.nursing.service.IMemberReservationService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +/** + * 创建定时任务,更新合同状态 + * + * @Author: Zhy + * @Date: 2025-02-27 19:16 + * @Version: 1.0 + */ +@Component("contractJob") +@RequiredArgsConstructor +public class ContractJob { + + private final IContractService contractService; + private final IMemberReservationService memberReservationService; + + public void updateContractStatus() { + contractService.updateContractStatus(); + } + + public void updateReservationStatus() { + memberReservationService.updateReservationStatus(); + } + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/job/CreateNursingTaskJob.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/job/CreateNursingTaskJob.java new file mode 100644 index 0000000..3248d52 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/job/CreateNursingTaskJob.java @@ -0,0 +1,29 @@ +package com.zzyl.nursing.job; + +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.zzyl.nursing.domain.Elder; +import com.zzyl.nursing.service.IElderService; +import com.zzyl.nursing.service.INursingTaskService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +@Slf4j +public class CreateNursingTaskJob { + + @Autowired + private IElderService elderService; + + @Autowired + private INursingTaskService nursingTaskService; + + public void createNursingTaskJob() { + //查询所有老人 + List elderList = elderService.list(Wrappers.lambdaQuery().eq(Elder::getStatus, 1)); + elderList.forEach(elder -> nursingTaskService.createMonthTask(elder) ); + log.info("创建月任务成功"); + } +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/job/MyJob.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/job/MyJob.java new file mode 100644 index 0000000..527da8d --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/job/MyJob.java @@ -0,0 +1,21 @@ +package com.zzyl.nursing.job; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * TODO + * + * @Author: Zhy + * @Date: 2025-02-27 17:17 + * @Version: 1.0 + */ +@Component("myJob") +@Slf4j +public class MyJob { + + public void executeTask(){ + log.info("MyJob executeTask"); + } + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/AlertDataMapper.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/AlertDataMapper.java new file mode 100644 index 0000000..4625c64 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/AlertDataMapper.java @@ -0,0 +1,76 @@ +package com.zzyl.nursing.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.zzyl.nursing.dto.AlertDataPageQueryDto; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +import com.zzyl.nursing.domain.AlertData; + +/** + * 报警数据Mapper接口 + * + * @author Zhy + * @date 2025-03-11 + */ +@Mapper +public interface AlertDataMapper extends BaseMapper { + + /** + * 查询报警数据 + * + * @param id 报警数据主键 + * @return 报警数据 + */ + public AlertData selectAlertDataById(Long id); + + /** + * 查询报警数据列表 + * + * @param alertData 报警数据 + * @return 报警数据集合 + */ + public List selectAlertDataList(AlertData alertData); + + /** + * 新增报警数据 + * + * @param alertData 报警数据 + * @return 结果 + */ + public int insertAlertData(AlertData alertData); + + /** + * 修改报警数据 + * + * @param alertData 报警数据 + * @return 结果 + */ + public int updateAlertData(AlertData alertData); + + /** + * 删除报警数据 + * + * @param id 报警数据主键 + * @return 结果 + */ + public int deleteAlertDataById(Long id); + + /** + * 批量删除报警数据 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteAlertDataByIds(Long[] ids); + + /** + * 查询报警数据列表 + * + * @return: + * @param: + */ + List pageQueryAlertData(AlertDataPageQueryDto alertDataPageQueryDto); + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/AlertRuleMapper.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/AlertRuleMapper.java new file mode 100644 index 0000000..e27d152 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/AlertRuleMapper.java @@ -0,0 +1,64 @@ +package com.zzyl.nursing.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import java.util.List; +import com.zzyl.nursing.domain.AlertRule; + +/** + * 报警规则Mapper接口 + * + * @author Zhy + * @date 2025-03-11 + */ +@Mapper +public interface AlertRuleMapper extends BaseMapper +{ + /** + * 查询报警规则 + * + * @param id 报警规则主键 + * @return 报警规则 + */ + public AlertRule selectAlertRuleById(Long id); + + /** + * 查询报警规则列表 + * + * @param alertRule 报警规则 + * @return 报警规则集合 + */ + public List selectAlertRuleList(AlertRule alertRule); + + /** + * 新增报警规则 + * + * @param alertRule 报警规则 + * @return 结果 + */ + public int insertAlertRule(AlertRule alertRule); + + /** + * 修改报警规则 + * + * @param alertRule 报警规则 + * @return 结果 + */ + public int updateAlertRule(AlertRule alertRule); + + /** + * 删除报警规则 + * + * @param id 报警规则主键 + * @return 结果 + */ + public int deleteAlertRuleById(Long id); + + /** + * 批量删除报警规则 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteAlertRuleByIds(Long[] ids); +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/BedMapper.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/BedMapper.java new file mode 100644 index 0000000..27774aa --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/BedMapper.java @@ -0,0 +1,67 @@ +package com.zzyl.nursing.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.zzyl.nursing.domain.Bed; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + * 床位Mapper接口 + * + * @author ruoyi + * @date 2024-04-26 + */ +@Mapper +public interface BedMapper extends BaseMapper +{ + /** + * 查询床位 + * + * @param id 床位主键 + * @return 床位 + */ + public Bed selectBedById(Long id); + + /** + * 查询床位列表 + * + * @param bed 床位 + * @return 床位集合 + */ + public List selectBedList(Bed bed); + + /** + * 新增床位 + * + * @param bed 床位 + * @return 结果 + */ + public int insertBed(Bed bed); + + /** + * 修改床位 + * + * @param bed 床位 + * @return 结果 + */ + public int updateBed(Bed bed); + + /** + * 删除床位 + * + * @param id 床位主键 + * @return 结果 + */ + public int deleteBedById(Long id); + + /** + * 批量删除床位 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteBedByIds(Long[] ids); + + String getRoomTypeNameByBedId(Long bedId); +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/CheckInConfigMapper.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/CheckInConfigMapper.java new file mode 100644 index 0000000..8c35ac2 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/CheckInConfigMapper.java @@ -0,0 +1,64 @@ +package com.zzyl.nursing.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import java.util.List; +import com.zzyl.nursing.domain.CheckInConfig; + +/** + * 入住配置表Mapper接口 + * + * @author Zhy + * @date 2025-02-25 + */ +@Mapper +public interface CheckInConfigMapper extends BaseMapper +{ + /** + * 查询入住配置表 + * + * @param id 入住配置表主键 + * @return 入住配置表 + */ + public CheckInConfig selectCheckInConfigById(Long id); + + /** + * 查询入住配置表列表 + * + * @param checkInConfig 入住配置表 + * @return 入住配置表集合 + */ + public List selectCheckInConfigList(CheckInConfig checkInConfig); + + /** + * 新增入住配置表 + * + * @param checkInConfig 入住配置表 + * @return 结果 + */ + public int insertCheckInConfig(CheckInConfig checkInConfig); + + /** + * 修改入住配置表 + * + * @param checkInConfig 入住配置表 + * @return 结果 + */ + public int updateCheckInConfig(CheckInConfig checkInConfig); + + /** + * 删除入住配置表 + * + * @param id 入住配置表主键 + * @return 结果 + */ + public int deleteCheckInConfigById(Long id); + + /** + * 批量删除入住配置表 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteCheckInConfigByIds(Long[] ids); +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/CheckInMapper.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/CheckInMapper.java new file mode 100644 index 0000000..fed8558 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/CheckInMapper.java @@ -0,0 +1,73 @@ +package com.zzyl.nursing.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.zzyl.nursing.vo.CheckInConfigVo; +import org.apache.ibatis.annotations.Mapper; +import java.util.List; +import com.zzyl.nursing.domain.CheckIn; + +/** + * 入住表Mapper接口 + * + * @author Zhy + * @date 2025-02-25 + */ +@Mapper +public interface CheckInMapper extends BaseMapper +{ + /** + * 查询入住表 + * + * @param id 入住表主键 + * @return 入住表 + */ + public CheckIn selectCheckInById(Long id); + + /** + * 查询入住表列表 + * + * @param checkIn 入住表 + * @return 入住表集合 + */ + public List selectCheckInList(CheckIn checkIn); + + /** + * 新增入住表 + * + * @param checkIn 入住表 + * @return 结果 + */ + public int insertCheckIn(CheckIn checkIn); + + /** + * 修改入住表 + * + * @param checkIn 入住表 + * @return 结果 + */ + public int updateCheckIn(CheckIn checkIn); + + /** + * 删除入住表 + * + * @param id 入住表主键 + * @return 结果 + */ + public int deleteCheckInById(Long id); + + /** + * 批量删除入住表 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteCheckInByIds(Long[] ids); + + /** + * 查询入住配置信息 + * + * @return: + * @param: id 入住ID + */ + CheckInConfigVo selectCheckInInfoById(Long id); +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/ContractMapper.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/ContractMapper.java new file mode 100644 index 0000000..c189122 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/ContractMapper.java @@ -0,0 +1,72 @@ +package com.zzyl.nursing.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import java.util.List; +import com.zzyl.nursing.domain.Contract; + +/** + * 合同表Mapper接口 + * + * @author Zhy + * @date 2025-02-25 + */ +@Mapper +public interface ContractMapper extends BaseMapper +{ + /** + * 查询合同表 + * + * @param id 合同表主键 + * @return 合同表 + */ + public Contract selectContractById(Integer id); + + /** + * 查询合同表列表 + * + * @param contract 合同表 + * @return 合同表集合 + */ + public List selectContractList(Contract contract); + + /** + * 新增合同表 + * + * @param contract 合同表 + * @return 结果 + */ + public int insertContract(Contract contract); + + /** + * 修改合同表 + * + * @param contract 合同表 + * @return 结果 + */ + public int updateContract(Contract contract); + + /** + * 删除合同表 + * + * @param id 合同表主键 + * @return 结果 + */ + public int deleteContractById(Integer id); + + /** + * 批量删除合同表 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteContractByIds(Integer[] ids); + + /** + * 根据入住ID查询合同信息 + * + * @return: + * @param: + */ + Contract selectContractByElderId(Long id); +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/DeviceDataMapper.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/DeviceDataMapper.java new file mode 100644 index 0000000..3ea81ca --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/DeviceDataMapper.java @@ -0,0 +1,76 @@ +package com.zzyl.nursing.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.MapKey; +import org.apache.ibatis.annotations.Mapper; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Map; + +import com.zzyl.nursing.domain.DeviceData; +import org.apache.ibatis.annotations.Param; + +/** + * 设备数据Mapper接口 + * + * @author Zhy + * @date 2025-03-08 + */ +@Mapper +public interface DeviceDataMapper extends BaseMapper +{ + /** + * 查询设备数据 + * + * @param id 设备数据主键 + * @return 设备数据 + */ + public DeviceData selectDeviceDataById(Long id); + + /** + * 查询设备数据列表 + * + * @param deviceData 设备数据 + * @return 设备数据集合 + */ + public List selectDeviceDataList(DeviceData deviceData); + + /** + * 新增设备数据 + * + * @param deviceData 设备数据 + * @return 结果 + */ + public int insertDeviceData(DeviceData deviceData); + + /** + * 修改设备数据 + * + * @param deviceData 设备数据 + * @return 结果 + */ + public int updateDeviceData(DeviceData deviceData); + + /** + * 删除设备数据 + * + * @param id 设备数据主键 + * @return 结果 + */ + public int deleteDeviceDataById(Long id); + + /** + * 批量删除设备数据 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteDeviceDataByIds(Long[] ids); + + @MapKey("data_value") + List> queryDeviceDataListByDay(@Param("functionId") String functionId, @Param("iotId") String iotId, @Param("startTime") LocalDateTime startTimeDate, @Param("endTime") LocalDateTime endTimeDate); + + @MapKey("data_value") + List> queryDeviceDataListByWeek(@Param("functionId") String functionId, @Param("iotId") String iotId, @Param("startTime") LocalDateTime startTimeDate, @Param("endTime") LocalDateTime endTimeDate); +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/DeviceMapper.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/DeviceMapper.java new file mode 100644 index 0000000..eae0539 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/DeviceMapper.java @@ -0,0 +1,81 @@ +package com.zzyl.nursing.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import java.util.List; +import com.zzyl.nursing.domain.Device; + +/** + * 设备Mapper接口 + * + * @author Zhy + * @date 2025-03-06 + */ +@Mapper +public interface DeviceMapper extends BaseMapper +{ + /** + * 查询设备 + * + * @param id 设备主键 + * @return 设备 + */ + Device selectDeviceById(Long id); + + /** + * 查询设备列表 + * + * @param device 设备 + * @return 设备集合 + */ + List selectDeviceList(Device device); + + /** + * 新增设备 + * + * @param device 设备 + * @return 结果 + */ + int insertDevice(Device device); + + /** + * 修改设备 + * + * @param device 设备 + * @return 结果 + */ + int updateDevice(Device device); + + /** + * 删除设备 + * + * @param id 设备主键 + * @return 结果 + */ + int deleteDeviceById(Long id); + + /** + * 批量删除设备 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + int deleteDeviceByIds(Long[] ids); + + /** + * 通过设备 id 查询护理人 + * + * @return: + * @param: + */ + List selectNursingIdsByIotIdWithElder(String iotId); + + /** + * 通过设备 id 查询护理人 + * + * @return: + * @param: + */ + List selectNursingIdsByIotIdWithBed(String iotId); + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/ElderMapper.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/ElderMapper.java new file mode 100644 index 0000000..956d1a8 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/ElderMapper.java @@ -0,0 +1,74 @@ +package com.zzyl.nursing.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.zzyl.nursing.vo.CheckInElderVo; +import org.apache.ibatis.annotations.Mapper; +import java.util.List; +import com.zzyl.nursing.domain.Elder; + +/** + * 老人Mapper接口 + * + * @author Zhy + * @date 2025-02-25 + */ +@Mapper +public interface ElderMapper extends BaseMapper +{ + /** + * 查询老人 + * + * @param id 老人主键 + * @return 老人 + */ + public Elder selectElderById(Long id); + + /** + * 查询老人列表 + * + * @param elder 老人 + * @return 老人集合 + */ + public List selectElderList(Elder elder); + + /** + * 新增老人 + * + * @param elder 老人 + * @return 结果 + */ + public int insertElder(Elder elder); + + /** + * 修改老人 + * + * @param elder 老人 + * @return 结果 + */ + public int updateElder(Elder elder); + + /** + * 删除老人 + * + * @param id 老人主键 + * @return 结果 + */ + public int deleteElderById(Long id); + + /** + * 批量删除老人 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteElderByIds(Long[] ids); + + + /** + * 根据入住ID查询老人数据 + * + * @return: + * @param: id 入住ID + */ + CheckInElderVo selectByCheckId(Long id); +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/FamilyMemberElderMapper.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/FamilyMemberElderMapper.java new file mode 100644 index 0000000..747ac3e --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/FamilyMemberElderMapper.java @@ -0,0 +1,25 @@ +package com.zzyl.nursing.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.zzyl.nursing.domain.FamilyMember; +import com.zzyl.nursing.dto.ElderDto; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 老人家属Mapper接口 + * + * @author Zhy + * @date 2025-03-03 + */ +@Mapper +public interface FamilyMemberElderMapper { + + void insert(ElderDto elderDto); + + List getMyElder(Long id); + + List getMyElderPage(@Param("userId") Long userId, @Param("startNum") Integer startNum, @Param("pageSize") Integer pageSize); +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/FamilyMemberMapper.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/FamilyMemberMapper.java new file mode 100644 index 0000000..7c646aa --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/FamilyMemberMapper.java @@ -0,0 +1,58 @@ +package com.zzyl.nursing.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import java.util.List; +import com.zzyl.nursing.domain.FamilyMember; + +/** + * 老人家属Mapper接口 + * + * @author Zhy + * @date 2025-03-03 + */ +@Mapper +public interface FamilyMemberMapper extends BaseMapper +{ + /** + * 查询老人家属 + * @param id 老人家属主键 + * @return 老人家属 + */ + public FamilyMember selectFamilyMemberById(Long id); + + /** + * 查询老人家属列表 + * @param familyMember 老人家属 + * @return 老人家属集合 + */ + public List selectFamilyMemberList(FamilyMember familyMember); + + /** + * 新增老人家属 + * @param familyMember 老人家属 + * @return 结果 + */ + public int insertFamilyMember(FamilyMember familyMember); + + /** + * 修改老人家属 + * @param familyMember 老人家属 + * @return 结果 + */ + public int updateFamilyMember(FamilyMember familyMember); + + /** + * 删除老人家属 + * @param id 老人家属主键 + * @return 结果 + */ + public int deleteFamilyMemberById(Long id); + + /** + * 批量删除老人家属 + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteFamilyMemberByIds(Long[] ids); +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/FloorMapper.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/FloorMapper.java new file mode 100644 index 0000000..8e33b3a --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/FloorMapper.java @@ -0,0 +1,97 @@ +package com.zzyl.nursing.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.zzyl.nursing.domain.Floor; +import com.zzyl.nursing.vo.FloorVo; +import com.zzyl.nursing.vo.TreeVo; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + * 楼层Mapper接口 + * + * @author ruoyi + * @date 2024-04-26 + */ +@Mapper +public interface FloorMapper extends BaseMapper +{ + /** + * 查询楼层 + * + * @param id 楼层主键 + * @return 楼层 + */ + public Floor selectFloorById(Long id); + + /** + * 查询楼层列表 + * + * @param floor 楼层 + * @return 楼层集合 + */ + public List selectFloorList(Floor floor); + + /** + * 新增楼层 + * + * @param floor 楼层 + * @return 结果 + */ + public int insertFloor(Floor floor); + + /** + * 修改楼层 + * + * @param floor 楼层 + * @return 结果 + */ + public int updateFloor(Floor floor); + + /** + * 删除楼层 + * + * @param id 楼层主键 + * @return 结果 + */ + public int deleteFloorById(Long id); + + /** + * 批量删除楼层 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteFloorByIds(Long[] ids); + + /** + * 查询所有楼层(负责老人) + * @return 结果 + */ + List selectAllByNur(); + + /** + * 获取所有楼层所有房间中的空床位 + * + * @return: + * @param: status 床位状态 + */ + List selectRoomAndBedByBedStatus(Integer status); + + /** + * 获取所有装有智能设备的楼层 + * + * @return: + * @param: + */ + List getAllFloorsWithDevice(); + + /** + * 获取所有楼层所有房间 + * + * @return: + * @param: + */ + List selectRoomAndBed(); +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/HealthAssessmentMapper.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/HealthAssessmentMapper.java new file mode 100644 index 0000000..97fed2f --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/HealthAssessmentMapper.java @@ -0,0 +1,64 @@ +package com.zzyl.nursing.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import java.util.List; +import com.zzyl.nursing.domain.HealthAssessment; + +/** + * 健康评估Mapper接口 + * + * @author Zhy + * @date 2025-02-28 + */ +@Mapper +public interface HealthAssessmentMapper extends BaseMapper +{ + /** + * 查询健康评估 + * + * @param id 健康评估主键 + * @return 健康评估 + */ + public HealthAssessment selectHealthAssessmentById(Long id); + + /** + * 查询健康评估列表 + * + * @param healthAssessment 健康评估 + * @return 健康评估集合 + */ + public List selectHealthAssessmentList(HealthAssessment healthAssessment); + + /** + * 新增健康评估 + * + * @param healthAssessment 健康评估 + * @return 结果 + */ + public int insertHealthAssessment(HealthAssessment healthAssessment); + + /** + * 修改健康评估 + * + * @param healthAssessment 健康评估 + * @return 结果 + */ + public int updateHealthAssessment(HealthAssessment healthAssessment); + + /** + * 删除健康评估 + * + * @param id 健康评估主键 + * @return 结果 + */ + public int deleteHealthAssessmentById(Long id); + + /** + * 批量删除健康评估 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteHealthAssessmentByIds(Long[] ids); +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/MemberReservationMapper.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/MemberReservationMapper.java new file mode 100644 index 0000000..39fd105 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/MemberReservationMapper.java @@ -0,0 +1,83 @@ +package com.zzyl.nursing.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +import java.time.LocalDateTime; +import java.util.List; + +import com.zzyl.nursing.domain.MemberReservation; +import org.apache.ibatis.annotations.Param; + +/** + * 预约信息Mapper接口 + * + * @author Zhy + * @date 2025-03-05 + */ +@Mapper +public interface MemberReservationMapper extends BaseMapper { + /** + * 查询预约信息 + * + * @param id 预约信息主键 + * @return 预约信息 + */ + public MemberReservation selectReservationById(Long id); + + /** + * 查询预约信息列表 + * + * @param reservation 预约信息 + * @return 预约信息集合 + */ + public List selectReservationList(MemberReservation reservation); + + /** + * 新增预约信息 + * + * @param reservation 预约信息 + * @return 结果 + */ + public int insertReservation(MemberReservation reservation); + + /** + * 修改预约信息 + * + * @param reservation 预约信息 + * @return 结果 + */ + public int updateReservation(MemberReservation reservation); + + /** + * 删除预约信息 + * + * @param id 预约信息主键 + * @return 结果 + */ + public int deleteReservationById(Long id); + + /** + * 批量删除预约信息 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteReservationByIds(Long[] ids); + + /** + * 查询当天取消预约数量 + * + * @return: + * @param: + */ + List selectReservationCount(@Param("userId") Long userId, @Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime); + + /** + * 取消预约 + * + * @return: + * @param: + */ + void updateStatus(Long id, int i); +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/NursingElderMapper.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/NursingElderMapper.java new file mode 100644 index 0000000..198f8b5 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/NursingElderMapper.java @@ -0,0 +1,81 @@ +package com.zzyl.nursing.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.zzyl.common.core.domain.entity.SysUser; +import com.zzyl.nursing.domain.NursingElder; +import com.zzyl.nursing.vo.NursingNameVo; +import org.apache.ibatis.annotations.*; + +import java.util.List; +import java.util.Set; + +/** + * 护理员老人关联Mapper接口 + * + * @author ruoyi + * @date 2024-05-28 + */ +@Mapper +public interface NursingElderMapper extends BaseMapper +{ + + @Select("select tu.user_id as userId, tu.nick_name from nursing_elder ne, sys_user tu where ne.elder_id = #{elderId} and tu.user_id = ne.nursing_id and tu.status = 0") + List selectUserByElderId(Long elderId); + + @Select("") + List selectNickNameByElderId(@Param("set") Set elderIds); + + /** + * 查询护理员老人关联 + * + * @param id 护理员老人关联主键 + * @return 护理员老人关联 + */ + @Select("") + public NursingElder selectNursingElderById(Long id); + + /** + * 查询护理员老人关联列表 + * + * @param nursingElder 护理员老人关联 + * @return 护理员老人关联集合 + */ + @Select("") + public List selectNursingElderList(NursingElder nursingElder); + + /** + * 新增护理员老人关联 + * + * @param nursingElder 护理员老人关联 + * @return 结果 + */ + @Insert("") + public int insertNursingElder(NursingElder nursingElder); + + /** + * 修改护理员老人关联 + * + * @param nursingElder 护理员老人关联 + * @return 结果 + */ + @Update("") + public int updateNursingElder(NursingElder nursingElder); + + /** + * 删除护理员老人关联 + * + * @param id 护理员老人关联主键 + * @return 结果 + */ + @Delete("") + public int deleteNursingElderById(Long id); + + /** + * 批量删除护理员老人关联 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + @Delete("") + public int deleteNursingElderByIds(Long[] ids); +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/NursingLevelMapper.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/NursingLevelMapper.java new file mode 100644 index 0000000..fea50ef --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/NursingLevelMapper.java @@ -0,0 +1,72 @@ +package com.zzyl.nursing.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.zzyl.nursing.vo.NursingLevelVo; +import org.apache.ibatis.annotations.Mapper; +import java.util.List; +import com.zzyl.nursing.domain.NursingLevel; + +/** + * 护理等级Mapper接口 + * + * @author alexis + * @date 2024-12-30 + */ +@Mapper +public interface NursingLevelMapper extends BaseMapper +{ + /** + * 查询护理等级 + * + * @param id 护理等级主键 + * @return 护理等级 + */ + public NursingLevel selectNursingLevelById(Long id); + + /** + * 查询护理等级列表 + * + * @param nursingLevel 护理等级 + * @return 护理等级集合 + */ + public List selectNursingLevelList(NursingLevel nursingLevel); + + /** + * 新增护理等级 + * + * @param nursingLevel 护理等级 + * @return 结果 + */ + public int insertNursingLevel(NursingLevel nursingLevel); + + /** + * 修改护理等级 + * + * @param nursingLevel 护理等级 + * @return 结果 + */ + public int updateNursingLevel(NursingLevel nursingLevel); + + /** + * 删除护理等级 + * + * @param id 护理等级主键 + * @return 结果 + */ + public int deleteNursingLevelById(Long id); + + /** + * 批量删除护理等级 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteNursingLevelByIds(Long[] ids); + + /** + * 查询护理等级Vo列表 + * @param nursingLevel 参数 + * @return 结果 + */ + List selectNursingLevelVoList(NursingLevel nursingLevel); +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/NursingPlanMapper.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/NursingPlanMapper.java new file mode 100644 index 0000000..315d40a --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/NursingPlanMapper.java @@ -0,0 +1,64 @@ +package com.zzyl.nursing.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import java.util.List; +import com.zzyl.nursing.domain.NursingPlan; + +/** + * 护理计划Mapper接口 + * + * @author alexis + * @date 2024-12-30 + */ +@Mapper +public interface NursingPlanMapper extends BaseMapper +{ + /** + * 查询护理计划 + * + * @param id 护理计划主键 + * @return 护理计划 + */ + public NursingPlan selectNursingPlanById(Long id); + + /** + * 查询护理计划列表 + * + * @param nursingPlan 护理计划 + * @return 护理计划集合 + */ + public List selectNursingPlanList(NursingPlan nursingPlan); + + /** + * 新增护理计划 + * + * @param nursingPlan 护理计划 + * @return 结果 + */ + public int insertNursingPlan(NursingPlan nursingPlan); + + /** + * 修改护理计划 + * + * @param nursingPlan 护理计划 + * @return 结果 + */ + public int updateNursingPlan(NursingPlan nursingPlan); + + /** + * 删除护理计划 + * + * @param id 护理计划主键 + * @return 结果 + */ + public int deleteNursingPlanById(Long id); + + /** + * 批量删除护理计划 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteNursingPlanByIds(Long[] ids); +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/NursingProjectMapper.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/NursingProjectMapper.java new file mode 100644 index 0000000..2b5f926 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/NursingProjectMapper.java @@ -0,0 +1,72 @@ +package com.zzyl.nursing.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.zzyl.nursing.vo.NursingProjectVo; +import org.apache.ibatis.annotations.Mapper; +import java.util.List; +import com.zzyl.nursing.domain.NursingProject; + +/** + * 护理项目Mapper接口 + * + * @Author: Zhy + * @Date: 2024-12-30 + */ +@Mapper +public interface NursingProjectMapper extends BaseMapper +{ + /** + * 查询护理项目 + * + * @param id 护理项目主键 + * @return 护理项目 + */ + public NursingProject selectNursingProjectById(Long id); + + /** + * 查询护理项目列表 + * + * @param nursingProject 护理项目 + * @return 护理项目集合 + */ + public List selectNursingProjectList(NursingProject nursingProject); + + /** + * 新增护理项目 + * + * @param nursingProject 护理项目 + * @return 结果 + */ + public int insertNursingProject(NursingProject nursingProject); + + /** + * 修改护理项目 + * + * @param nursingProject 护理项目 + * @return 结果 + */ + public int updateNursingProject(NursingProject nursingProject); + + /** + * 删除护理项目 + * + * @param id 护理项目主键 + * @return 结果 + */ + public int deleteNursingProjectById(Long id); + + /** + * 批量删除护理项目 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteNursingProjectByIds(Long[] ids); + + /** + * 获取护理项目列表 + * @return 护理项目vo列表 + */ + List getAllProjects(); + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/NursingProjectPlanMapper.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/NursingProjectPlanMapper.java new file mode 100644 index 0000000..8f41968 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/NursingProjectPlanMapper.java @@ -0,0 +1,98 @@ +package com.zzyl.nursing.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.zzyl.nursing.vo.NursingProjectPlanVo; +import org.apache.ibatis.annotations.Delete; +import org.apache.ibatis.annotations.Mapper; +import java.util.List; +import com.zzyl.nursing.domain.NursingProjectPlan; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; + +/** + * 护理计划和项目关联Mapper接口 + * + * @author alexis + * @date 2024-12-31 + */ +@Mapper +public interface NursingProjectPlanMapper extends BaseMapper +{ + /** + * 查询护理计划和项目关联 + * + * @param id 护理计划和项目关联主键 + * @return 护理计划和项目关联 + */ + public NursingProjectPlan selectNursingProjectPlanById(Long id); + + /** + * 查询护理计划和项目关联列表 + * + * @param nursingProjectPlan 护理计划和项目关联 + * @return 护理计划和项目关联集合 + */ + public List selectNursingProjectPlanList(NursingProjectPlan nursingProjectPlan); + + /** + * 新增护理计划和项目关联 + * + * @param nursingProjectPlan 护理计划和项目关联 + * @return 结果 + */ + public int insertNursingProjectPlan(NursingProjectPlan nursingProjectPlan); + + /** + * 修改护理计划和项目关联 + * + * @param nursingProjectPlan 护理计划和项目关联 + * @return 结果 + */ + public int updateNursingProjectPlan(NursingProjectPlan nursingProjectPlan); + + /** + * 删除护理计划和项目关联 + * + * @param id 护理计划和项目关联主键 + * @return 结果 + */ + public int deleteNursingProjectPlanById(Long id); + + /** + * 批量删除护理计划和项目关联 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteNursingProjectPlanByIds(Long[] ids); + + /** + * 批量保存护理计划关联的护理项目 + * @param projectPlans 护理计划关联的护理项目集合 + * @param planId 护理计划id + * @return + */ + int insertBatch(@Param("projectPlans") List projectPlans, @Param("planId") Long planId); + + + /** + * 根据护理计划id查询关联的护理项目列表 + * @param planId + * @return + */ + @Select("select id, plan_id, project_id, execute_time, execute_cycle, execute_frequency, create_time, update_time, create_by, update_by, remark from nursing_project_plan where plan_id = #{planId}") + List getProjectListByPlanId(@Param("planId") Long planId); + + /** + * 根据护理计划id删除关联的护理项目 + * @param planId 护理计划id + */ + @Delete("delete from nursing_project_plan where plan_id = #{planId}") + void deleteByPlanId(@Param("planId") Long planId); + + /** + * 根据护理计划id集合批量删除关联的护理项目 + * @param ids 护理计划id集合 + */ + void batchDeleteByPlanIds(@Param("ids") List ids); +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/NursingTaskMapper.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/NursingTaskMapper.java new file mode 100644 index 0000000..c65c9f9 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/NursingTaskMapper.java @@ -0,0 +1,64 @@ +package com.zzyl.nursing.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import java.util.List; +import com.zzyl.nursing.domain.NursingTask; + +/** + * 护理任务Mapper接口 + * + * @author alexis + * @date 2024-11-17 + */ +@Mapper +public interface NursingTaskMapper extends BaseMapper +{ + /** + * 查询护理任务 + * + * @param id 护理任务主键 + * @return 护理任务 + */ + public NursingTask selectNursingTaskById(Long id); + + /** + * 查询护理任务列表 + * + * @param nursingTask 护理任务 + * @return 护理任务集合 + */ + public List selectNursingTaskList(NursingTask nursingTask); + + /** + * 新增护理任务 + * + * @param nursingTask 护理任务 + * @return 结果 + */ + public int insertNursingTask(NursingTask nursingTask); + + /** + * 修改护理任务 + * + * @param nursingTask 护理任务 + * @return 结果 + */ + public int updateNursingTask(NursingTask nursingTask); + + /** + * 删除护理任务 + * + * @param id 护理任务主键 + * @return 结果 + */ + public int deleteNursingTaskById(Long id); + + /** + * 批量删除护理任务 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteNursingTaskByIds(Long[] ids); +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/RoomMapper.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/RoomMapper.java new file mode 100644 index 0000000..402e782 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/RoomMapper.java @@ -0,0 +1,86 @@ +package com.zzyl.nursing.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.zzyl.nursing.domain.Room; +import com.zzyl.nursing.vo.RoomVo; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + * 房间Mapper接口 + * + * @author ruoyi + * @date 2024-04-26 + */ +@Mapper +public interface RoomMapper extends BaseMapper +{ + /** + * 查询房间 + * + * @param id 房间主键 + * @return 房间 + */ + public Room selectRoomById(Long id); + + /** + * 查询房间列表 + * + * @param room 房间 + * @return 房间集合 + */ + public List selectRoomList(Room room); + + /** + * 新增房间 + * + * @param room 房间 + * @return 结果 + */ + public int insertRoom(Room room); + + /** + * 修改房间 + * + * @param room 房间 + * @return 结果 + */ + public int updateRoom(Room room); + + /** + * 删除房间 + * + * @param id 房间主键 + * @return 结果 + */ + public int deleteRoomById(Long id); + + /** + * 批量删除房间 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteRoomByIds(Long[] ids); + + List selectByFloorId(Long floorId); + + List selectByFloorIdWithNur(Long floorId); + + /** + * 根据房间id查询 房间 数据 + * + * @return: + * @param: + */ + RoomVo selectRoomPriceByRoomId(Long id); + +/** + * 获取房间中的智能设备及数据 + * + * @return: + * @param: + */ + List getRoomsWithDeviceByFloorId(Long floorId); +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/RoomTypeMapper.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/RoomTypeMapper.java new file mode 100644 index 0000000..83a0c28 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/mapper/RoomTypeMapper.java @@ -0,0 +1,65 @@ +package com.zzyl.nursing.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.zzyl.nursing.domain.RoomType; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + * 房型Mapper接口 + * + * @author ruoyi + * @date 2024-04-26 + */ +@Mapper +public interface RoomTypeMapper extends BaseMapper +{ + /** + * 查询房型 + * + * @param id 房型主键 + * @return 房型 + */ + public RoomType selectRoomTypeById(Long id); + + /** + * 查询房型列表 + * + * @param roomType 房型 + * @return 房型集合 + */ + public List selectRoomTypeList(RoomType roomType); + + /** + * 新增房型 + * + * @param roomType 房型 + * @return 结果 + */ + public int insertRoomType(RoomType roomType); + + /** + * 修改房型 + * + * @param roomType 房型 + * @return 结果 + */ + public int updateRoomType(RoomType roomType); + + /** + * 删除房型 + * + * @param id 房型主键 + * @return 结果 + */ + public int deleteRoomTypeById(Long id); + + /** + * 批量删除房型 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteRoomTypeByIds(Long[] ids); +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/IAlertDataService.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/IAlertDataService.java new file mode 100644 index 0000000..ef71a48 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/IAlertDataService.java @@ -0,0 +1,80 @@ +package com.zzyl.nursing.service; + +import java.util.List; +import com.zzyl.nursing.domain.AlertData; +import com.baomidou.mybatisplus.extension.service.IService; +import com.zzyl.nursing.dto.AlertDataPageQueryDto; +import com.zzyl.nursing.dto.HandleAlertDataDto; + +/** + * 报警数据Service接口 + * + * @author Zhy + * @date 2025-03-11 + */ +public interface IAlertDataService extends IService +{ + /** + * 查询报警数据 + * + * @param id 报警数据主键 + * @return 报警数据 + */ + public AlertData selectAlertDataById(Long id); + + /** + * 查询报警数据列表 + * + * @param alertData 报警数据 + * @return 报警数据集合 + */ + public List selectAlertDataList(AlertData alertData); + + /** + * 新增报警数据 + * + * @param alertData 报警数据 + * @return 结果 + */ + public int insertAlertData(AlertData alertData); + + /** + * 修改报警数据 + * + * @param alertData 报警数据 + * @return 结果 + */ + public int updateAlertData(AlertData alertData); + + /** + * 批量删除报警数据 + * + * @param ids 需要删除的报警数据主键集合 + * @return 结果 + */ + public int deleteAlertDataByIds(Long[] ids); + + /** + * 删除报警数据信息 + * + * @param id 报警数据主键 + * @return 结果 + */ + public int deleteAlertDataById(Long id); + + /** + * 查询报警数据列表 + * + * @return: + * @param: + */ + List pageQueryAlertData(AlertDataPageQueryDto alertDataPageQueryDto); + + /** + * 处理设备报警数据 + * + * @return: + * @param: + */ + void handleAlertData(HandleAlertDataDto handleAlertDataDto); +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/IAlertRuleService.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/IAlertRuleService.java new file mode 100644 index 0000000..7aea56a --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/IAlertRuleService.java @@ -0,0 +1,78 @@ +package com.zzyl.nursing.service; + +import java.util.List; + +import com.zzyl.nursing.domain.AlertRule; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + * 报警规则Service接口 + * + * @author Zhy + * @date 2025-03-11 + */ +public interface IAlertRuleService extends IService { + /** + * 查询报警规则 + * + * @param id 报警规则主键 + * @return 报警规则 + */ + public AlertRule selectAlertRuleById(Long id); + + /** + * 查询报警规则列表 + * + * @param alertRule 报警规则 + * @return 报警规则集合 + */ + public List selectAlertRuleList(AlertRule alertRule); + + /** + * 新增报警规则 + * + * @param alertRule 报警规则 + * @return 结果 + */ + public int insertAlertRule(AlertRule alertRule); + + /** + * 修改报警规则 + * + * @param alertRule 报警规则 + * @return 结果 + */ + public int updateAlertRule(AlertRule alertRule); + + /** + * 批量删除报警规则 + * + * @param ids 需要删除的报警规则主键集合 + * @return 结果 + */ + public int deleteAlertRuleByIds(Long[] ids); + + /** + * 删除报警规则信息 + * + * @param id 报警规则主键 + * @return 结果 + */ + public int deleteAlertRuleById(Long id); + + /** + * 新增报警规则 + * + * @return: + * @param: + */ + void createAlertRule(AlertRule alertRule); + + /** + * 设备数据异常告警 + * + * @return: + * @param: + */ + void alertFilter(); +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/IBedService.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/IBedService.java new file mode 100644 index 0000000..0bb5d78 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/IBedService.java @@ -0,0 +1,63 @@ +package com.zzyl.nursing.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.zzyl.nursing.domain.Bed; + +import java.util.List; + +/** + * 床位Service接口 + * + * @author ruoyi + * @date 2024-04-26 + */ +public interface IBedService extends IService +{ + /** + * 查询床位 + * + * @param id 床位主键 + * @return 床位 + */ + public Bed selectBedById(Long id); + + /** + * 查询床位列表 + * + * @param bed 床位 + * @return 床位集合 + */ + public List selectBedList(Bed bed); + + /** + * 新增床位 + * + * @param bed 床位 + * @return 结果 + */ + public int insertBed(Bed bed); + + /** + * 修改床位 + * + * @param bed 床位 + * @return 结果 + */ + public int updateBed(Bed bed); + + /** + * 批量删除床位 + * + * @param ids 需要删除的床位主键集合 + * @return 结果 + */ + public int deleteBedByIds(Long[] ids); + + /** + * 删除床位信息 + * + * @param id 床位主键 + * @return 结果 + */ + public int deleteBedById(Long id); +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/ICheckInConfigService.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/ICheckInConfigService.java new file mode 100644 index 0000000..6acf831 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/ICheckInConfigService.java @@ -0,0 +1,62 @@ +package com.zzyl.nursing.service; + +import java.util.List; +import com.zzyl.nursing.domain.CheckInConfig; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + * 入住配置表Service接口 + * + * @Author: Zhy + * @Date: 2025-02-25 + */ +public interface ICheckInConfigService extends IService +{ + /** + * 查询入住配置表 + * + * @param id 入住配置表主键 + * @return 入住配置表 + */ + public CheckInConfig selectCheckInConfigById(Long id); + + /** + * 查询入住配置表列表 + * + * @param checkInConfig 入住配置表 + * @return 入住配置表集合 + */ + public List selectCheckInConfigList(CheckInConfig checkInConfig); + + /** + * 新增入住配置表 + * + * @param checkInConfig 入住配置表 + * @return 结果 + */ + public int insertCheckInConfig(CheckInConfig checkInConfig); + + /** + * 修改入住配置表 + * + * @param checkInConfig 入住配置表 + * @return 结果 + */ + public int updateCheckInConfig(CheckInConfig checkInConfig); + + /** + * 批量删除入住配置表 + * + * @param ids 需要删除的入住配置表主键集合 + * @return 结果 + */ + public int deleteCheckInConfigByIds(Long[] ids); + + /** + * 删除入住配置表信息 + * + * @param id 入住配置表主键 + * @return 结果 + */ + public int deleteCheckInConfigById(Long id); +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/ICheckInService.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/ICheckInService.java new file mode 100644 index 0000000..0f26e9e --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/ICheckInService.java @@ -0,0 +1,80 @@ +package com.zzyl.nursing.service; + +import java.util.List; + +import com.zzyl.nursing.domain.CheckIn; +import com.baomidou.mybatisplus.extension.service.IService; +import com.zzyl.nursing.dto.CheckInApplyDto; +import com.zzyl.nursing.vo.CheckInDetailVo; + +/** + * 入住表Service接口 + * + * @Author: Zhy + * @Date: 2025-02-25 + */ +public interface ICheckInService extends IService { + /** + * 查询入住表 + * + * @param id 入住表主键 + * @return 入住表 + */ + public CheckIn selectCheckInById(Long id); + + /** + * 查询入住表列表 + * + * @param checkIn 入住表 + * @return 入住表集合 + */ + public List selectCheckInList(CheckIn checkIn); + + /** + * 新增入住表 + * + * @param checkIn 入住表 + * @return 结果 + */ + public int insertCheckIn(CheckIn checkIn); + + /** + * 修改入住表 + * + * @param checkIn 入住表 + * @return 结果 + */ + public int updateCheckIn(CheckIn checkIn); + + /** + * 批量删除入住表 + * + * @param ids 需要删除的入住表主键集合 + * @return 结果 + */ + public int deleteCheckInByIds(Long[] ids); + + /** + * 删除入住表信息 + * + * @param id 入住表主键 + * @return 结果 + */ + public int deleteCheckInById(Long id); + + /** + * 申请入住 + * + * @return: + * @param: + */ + void apply(CheckInApplyDto checkInApplyDto); + + /** + * 入住详情 + * + * @return: + * @param: id 入住id + */ + CheckInDetailVo getCheckInInfo(Long id); +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/IContractService.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/IContractService.java new file mode 100644 index 0000000..078fb73 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/IContractService.java @@ -0,0 +1,70 @@ +package com.zzyl.nursing.service; + +import java.util.List; +import com.zzyl.nursing.domain.Contract; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + * 合同表Service接口 + * + * @Author: Zhy + * @Date: 2025-02-25 + */ +public interface IContractService extends IService +{ + /** + * 查询合同表 + * + * @param id 合同表主键 + * @return 合同表 + */ + public Contract selectContractById(Integer id); + + /** + * 查询合同表列表 + * + * @param contract 合同表 + * @return 合同表集合 + */ + public List selectContractList(Contract contract); + + /** + * 新增合同表 + * + * @param contract 合同表 + * @return 结果 + */ + public int insertContract(Contract contract); + + /** + * 修改合同表 + * + * @param contract 合同表 + * @return 结果 + */ + public int updateContract(Contract contract); + + /** + * 批量删除合同表 + * + * @param ids 需要删除的合同表主键集合 + * @return 结果 + */ + public int deleteContractByIds(Integer[] ids); + + /** + * 删除合同表信息 + * + * @param id 合同表主键 + * @return 结果 + */ + public int deleteContractById(Integer id); + + /** + * 更新合同状态 + * + * @return: + * @param: + */ + int updateContractStatus(); +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/IDeviceDataService.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/IDeviceDataService.java new file mode 100644 index 0000000..27af46b --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/IDeviceDataService.java @@ -0,0 +1,81 @@ +package com.zzyl.nursing.service; + +import java.util.List; + +import com.zzyl.common.core.page.TableDataInfo; +import com.zzyl.nursing.domain.DeviceData; +import com.baomidou.mybatisplus.extension.service.IService; +import com.zzyl.nursing.dto.DeviceDataPageReqDto; +import com.zzyl.nursing.vo.IotMsgNotifyData; + +/** + * 设备数据Service接口 + * + * @author Zhy + * @date 2025-03-08 + */ +public interface IDeviceDataService extends IService +{ + /** + * 查询设备数据 + * + * @param id 设备数据主键 + * @return 设备数据 + */ + public DeviceData selectDeviceDataById(Long id); + + /** + * 查询设备数据列表 + * + * @param deviceData 设备数据 + * @return 设备数据集合 + */ + public List selectDeviceDataList(DeviceData deviceData); + + /** + * 新增设备数据 + * + * @param deviceData 设备数据 + * @return 结果 + */ + public int insertDeviceData(DeviceData deviceData); + + /** + * 修改设备数据 + * + * @param deviceData 设备数据 + * @return 结果 + */ + public int updateDeviceData(DeviceData deviceData); + + /** + * 批量删除设备数据 + * + * @param ids 需要删除的设备数据主键集合 + * @return 结果 + */ + public int deleteDeviceDataByIds(Long[] ids); + + /** + * 删除设备数据信息 + * + * @param id 设备数据主键 + * @return 结果 + */ + public int deleteDeviceDataById(Long id); + + /** + * 批量保存数据 + * + * @param iotMsgNotifyData 设备数据集合 + */ + void batchInsertDeviceData(IotMsgNotifyData iotMsgNotifyData); + + /** + * 分页查询设备数据列表 + * + * @return: + * @param: + */ + TableDataInfo selectDeviceDataPageList(DeviceDataPageReqDto deviceDataPageReqDto); +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/IDeviceService.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/IDeviceService.java new file mode 100644 index 0000000..99b2559 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/IDeviceService.java @@ -0,0 +1,92 @@ +package com.zzyl.nursing.service; + +import java.util.List; + +import com.huaweicloud.sdk.iotda.v5.model.ServiceCapability; +import com.zzyl.nursing.domain.Device; +import com.baomidou.mybatisplus.extension.service.IService; +import com.zzyl.nursing.dto.DeviceDto; +import com.zzyl.nursing.vo.DeviceDetailVo; +import com.zzyl.nursing.vo.DeviceReportDataVo; +import com.zzyl.nursing.vo.ProductVo; + +/** + * 设备Service接口 + * + * @author Zhy + * @date 2025-03-06 + */ +public interface IDeviceService extends IService { + + /** + * 查询设备列表 + * + * @param device 设备 + * @return 设备集合 + */ + List selectDeviceList(Device device); + + /** + * 从物联网平台同步产品列表 + * + * @return: + * @param: + */ + void syncProductList(); + + /** + * 查询所有产品列表 + * + * @return: + * @param: + */ + List allProduct(); + + /** + * 注册设备 + * + * @return: + * @param: + */ + void registerProduct(DeviceDto deviceDto); + + /** + * 查询设备详细数据 + * + * @return: + * @param: + */ + DeviceDetailVo queryDeviceDetail(String iotId); + + /** + * 查询设备上报数据 + * + * @return: + * @param: + */ + List queryDeviceReportData(String iotId); + + /** + * 更新设备数据 + * + * @return: + * @param: + */ + void updateDevice(Device device); + + /** + * 删除设备 + * + * @return: + * @param: + */ + void deleteDeviceByIotId(String iotId); + + /** + * 获取产品对应的服务信息 + * + * @return: + * @param: + */ + List queryProductByProductKey(String productKey); +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/IElderService.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/IElderService.java new file mode 100644 index 0000000..e24fdba --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/IElderService.java @@ -0,0 +1,72 @@ +package com.zzyl.nursing.service; + +import java.util.List; + +import com.zzyl.common.core.page.TableDataInfo; +import com.zzyl.nursing.domain.Elder; +import com.baomidou.mybatisplus.extension.service.IService; +import com.zzyl.nursing.dto.ElderPageQuery; + +/** + * 老人Service接口 + * + * @Author: Zhy + * @Date: 2025-02-25 + */ +public interface IElderService extends IService { + /** + * 查询老人 + * + * @param id 老人主键 + * @return 老人 + */ + public Elder selectElderById(Long id); + + /** + * 查询老人列表 + * + * @param elder 老人 + * @return 老人集合 + */ + public List selectElderList(Elder elder); + + /** + * 新增老人 + * + * @param elder 老人 + * @return 结果 + */ + public int insertElder(Elder elder); + + /** + * 修改老人 + * + * @param elder 老人 + * @return 结果 + */ + public int updateElder(Elder elder); + + /** + * 批量删除老人 + * + * @param ids 需要删除的老人主键集合 + * @return 结果 + */ + public int deleteElderByIds(Long[] ids); + + /** + * 删除老人信息 + * + * @param id 老人主键 + * @return 结果 + */ + public int deleteElderById(Long id); + + /** + * 查询已经入住的老人列表 + * + * @return: + * @param: + */ + TableDataInfo pageQuery(ElderPageQuery elderPageQuery); +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/IFamilyMemberService.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/IFamilyMemberService.java new file mode 100644 index 0000000..d90306e --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/IFamilyMemberService.java @@ -0,0 +1,89 @@ +package com.zzyl.nursing.service; + +import java.util.List; +import java.util.Map; + +import com.zzyl.nursing.domain.FamilyMember; +import com.baomidou.mybatisplus.extension.service.IService; +import com.zzyl.nursing.dto.ElderDto; +import com.zzyl.nursing.dto.QueryDevicePropertyDto; +import com.zzyl.nursing.dto.UserLoginRequestDto; +import com.zzyl.nursing.vo.DevicePropertyVo; +import com.zzyl.nursing.vo.FamilyMemberElderVo; +import com.zzyl.nursing.vo.LoginVo; + +/** + * 老人家属Service接口 + * + * @author Zhy + * @date 2025-03-03 + */ +public interface IFamilyMemberService extends IService { + /** + * 查询老人家属 + * + * @param id 老人家属主键 + * @return 老人家属 + */ + public FamilyMember selectFamilyMemberById(Long id); + + /** + * 查询老人家属列表 + * + * @param familyMember 老人家属 + * @return 老人家属集合 + */ + public List selectFamilyMemberList(FamilyMember familyMember); + + /** + * 新增老人家属 + * + * @param familyMember 老人家属 + * @return 结果 + */ + public int insertFamilyMember(FamilyMember familyMember); + + /** + * 修改老人家属 + * + * @param familyMember 老人家属 + * @return 结果 + */ + public int updateFamilyMember(FamilyMember familyMember); + + /** + * 批量删除老人家属 + * + * @param ids 需要删除的老人家属主键集合 + * @return 结果 + */ + public int deleteFamilyMemberByIds(Long[] ids); + + /** + * 删除老人家属信息 + * + * @param id 老人家属主键 + * @return 结果 + */ + public int deleteFamilyMemberById(Long id); + + /** + * 小程序登录 + * + * @return: + * @param: + */ + LoginVo login(UserLoginRequestDto userLoginRequestDto); + + void addMember(ElderDto elderDto); + + List getMyElder(); + + List listByPage(Integer pageNum, Integer pageSize); + + DevicePropertyVo queryDevicePropertyStatus(QueryDevicePropertyDto queryDevicePropertyDto); + + List> queryDeviceDataListByDay(String functionId, String iotId, Long startTime, Long endTime); + + List> queryDeviceDataListByWeek(String functionId, String iotId, Long startTime, Long endTime); +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/IFloorService.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/IFloorService.java new file mode 100644 index 0000000..5fbdab0 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/IFloorService.java @@ -0,0 +1,87 @@ +package com.zzyl.nursing.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.zzyl.nursing.domain.Floor; +import com.zzyl.nursing.vo.FloorVo; +import com.zzyl.nursing.vo.TreeVo; + +import java.util.List; + +/** + * 楼层Service接口 + * + * @author ruoyi + * @date 2024-04-26 + */ +public interface IFloorService extends IService +{ + /** + * 查询楼层 + * + * @param id 楼层主键 + * @return 楼层 + */ + public Floor selectFloorById(Long id); + + /** + * 新增楼层 + * + * @param floor 楼层 + * @return 结果 + */ + public int insertFloor(Floor floor); + + /** + * 修改楼层 + * + * @param floor 楼层 + * @return 结果 + */ + public int updateFloor(Floor floor); + + /** + * 批量删除楼层 + * + * @param ids 需要删除的楼层主键集合 + * @return 结果 + */ + public int deleteFloorByIds(Long[] ids); + + /** + * 删除楼层信息 + * + * @param id 楼层主键 + * @return 结果 + */ + public int deleteFloorById(Long id); + + /** + * 查询所有楼层(负责老人) + * @return + */ + List selectAllByNur(); + + /** + * 获取所有楼层所有房间中的空床位 + * + * @return: + * @param: + */ + List getRoomAndBedByBedStatus(Integer status); + + /** + * 获取所有装有智能设备的楼层 + * + * @return: + * @param: + */ + List getAllFloorsWithDevice(); + + /** + * 获取所有楼层 + * + * @return: + * @param: + */ + List getRoomAndBed(); +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/IHealthAssessmentService.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/IHealthAssessmentService.java new file mode 100644 index 0000000..ea6f4b2 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/IHealthAssessmentService.java @@ -0,0 +1,74 @@ +package com.zzyl.nursing.service; + +import java.util.List; + +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.nursing.domain.HealthAssessment; +import com.baomidou.mybatisplus.extension.service.IService; +import com.zzyl.nursing.dto.HealthAssessmentDto; +import org.springframework.web.multipart.MultipartFile; + +/** + * 健康评估Service接口 + * + * @Author: Zhy + * @Date: 2025-02-28 + */ +public interface IHealthAssessmentService extends IService +{ + /** + * 查询健康评估 + * + * @param id 健康评估主键 + * @return 健康评估 + */ + public HealthAssessment selectHealthAssessmentById(Long id); + + /** + * 查询健康评估列表 + * + * @param healthAssessment 健康评估 + * @return 健康评估集合 + */ + public List selectHealthAssessmentList(HealthAssessment healthAssessment); + + /** + * 新增健康评估 + * + * @param healthAssessmentDto 健康评估 + * @return 结果 + */ + public Long insertHealthAssessment(HealthAssessmentDto healthAssessmentDto); + + /** + * 修改健康评估 + * + * @param healthAssessment 健康评估 + * @return 结果 + */ + public int updateHealthAssessment(HealthAssessment healthAssessment); + + /** + * 批量删除健康评估 + * + * @param ids 需要删除的健康评估主键集合 + * @return 结果 + */ + public int deleteHealthAssessmentByIds(Long[] ids); + + /** + * 删除健康评估信息 + * + * @param id 健康评估主键 + * @return 结果 + */ + public int deleteHealthAssessmentById(Long id); + + /** + * 体检报告上传 + * + * @return: + * @param: + */ + AjaxResult uploadFile(String idCard, MultipartFile file); +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/IMemberReservationService.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/IMemberReservationService.java new file mode 100644 index 0000000..550d0a5 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/IMemberReservationService.java @@ -0,0 +1,85 @@ +package com.zzyl.nursing.service; + +import java.util.List; +import com.zzyl.nursing.domain.MemberReservation; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + * 预约信息Service接口 + * + * @author Zhy + * @date 2025-03-05 + */ +public interface IMemberReservationService extends IService +{ + /** + * 查询预约信息 + * + * @param id 预约信息主键 + * @return 预约信息 + */ + public MemberReservation selectReservationById(Long id); + + /** + * 查询预约信息列表 + * + * @param reservation 预约信息 + * @return 预约信息集合 + */ + public List selectReservationList(MemberReservation reservation); + + /** + * 新增预约信息 + * + * @param memberReservation 预约信息 + */ + void insertReservation(MemberReservation memberReservation); + + /** + * 修改预约信息 + * + * @param reservation 预约信息 + * @return 结果 + */ + public int updateReservation(MemberReservation reservation); + + /** + * 批量删除预约信息 + * + * @param ids 需要删除的预约信息主键集合 + * @return 结果 + */ + public int deleteReservationByIds(Long[] ids); + + /** + * 删除预约信息信息 + * + * @param id 预约信息主键 + * @return 结果 + */ + public int deleteReservationById(Long id); + + /** + * 查询当天取消预约数量 + * + * @return: + * @param: + */ + Integer selectReservationCount(); + + /** + * 取消预约 + * + * @return: + * @param: + */ + void updateReservationById(Long id); + + /** + * 定时更新预约状态 + * + * @return: + * @param: + */ + void updateReservationStatus(); +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/INursingElderService.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/INursingElderService.java new file mode 100644 index 0000000..24709bf --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/INursingElderService.java @@ -0,0 +1,67 @@ +package com.zzyl.nursing.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.zzyl.nursing.domain.NursingElder; +import com.zzyl.nursing.dto.NursingElderDto; + +import java.util.List; + +/** + * 护理员老人关联Service接口 + * + * @author ruoyi + * @date 2024-05-28 + */ +public interface INursingElderService extends IService +{ + /** + * 查询护理员老人关联 + * + * @param id 护理员老人关联主键 + * @return 护理员老人关联 + */ + public NursingElder selectNursingElderById(Long id); + + /** + * 查询护理员老人关联列表 + * + * @param nursingElder 护理员老人关联 + * @return 护理员老人关联集合 + */ + public List selectNursingElderList(NursingElder nursingElder); + + /** + * 新增护理员老人关联 + * + * @param nursingElder 护理员老人关联 + * @return 结果 + */ + public int insertNursingElder(NursingElder nursingElder); + + /** + * 修改护理员老人关联 + * + * @param nursingElder 护理员老人关联 + * @return 结果 + */ + public int updateNursingElder(NursingElder nursingElder); + + /** + * 批量删除护理员老人关联 + * + * @param ids 需要删除的护理员老人关联主键集合 + * @return 结果 + */ + public int deleteNursingElderByIds(Long[] ids); + + /** + * 删除护理员老人关联信息 + * + * @param id 护理员老人关联主键 + * @return 结果 + */ + public int deleteNursingElderById(Long id); + + Boolean setNursingElder(List nursingElderDtos); + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/INursingLevelService.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/INursingLevelService.java new file mode 100644 index 0000000..0fab7df --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/INursingLevelService.java @@ -0,0 +1,78 @@ +package com.zzyl.nursing.service; + +import java.util.List; +import com.zzyl.nursing.domain.NursingLevel; +import com.baomidou.mybatisplus.extension.service.IService; +import com.zzyl.nursing.vo.NursingLevelVo; + +/** + * 护理等级Service接口 + * + * @author alexis + * @date 2024-12-30 + */ +public interface INursingLevelService extends IService +{ + /** + * 查询护理等级 + * + * @param id 护理等级主键 + * @return 护理等级 + */ + public NursingLevel selectNursingLevelById(Long id); + + /** + * 查询护理等级列表 + * + * @param nursingLevel 护理等级 + * @return 护理等级集合 + */ + public List selectNursingLevelList(NursingLevel nursingLevel); + + /** + * 新增护理等级 + * + * @param nursingLevel 护理等级 + * @return 结果 + */ + public int insertNursingLevel(NursingLevel nursingLevel); + + /** + * 修改护理等级 + * + * @param nursingLevel 护理等级 + * @return 结果 + */ + public int updateNursingLevel(NursingLevel nursingLevel); + + /** + * 批量删除护理等级 + * + * @param ids 需要删除的护理等级主键集合 + * @return 结果 + */ + public int deleteNursingLevelByIds(Long[] ids); + + /** + * 删除护理等级信息 + * + * @param id 护理等级主键 + * @return 结果 + */ + public int deleteNursingLevelById(Long id); + + /** + * 查询护理等级Vo列表 + * @param nursingLevel 条件 + * @return 结果 + */ + List selectNursingLevelVoList(NursingLevel nursingLevel); + + /** + * 查询所有已启用的护理等级 + * + * @return: + * @param: + */ + List selectByEnable(); +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/INursingPlanService.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/INursingPlanService.java new file mode 100644 index 0000000..86228bb --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/INursingPlanService.java @@ -0,0 +1,70 @@ +package com.zzyl.nursing.service; + +import java.util.List; +import com.zzyl.nursing.domain.NursingPlan; +import com.baomidou.mybatisplus.extension.service.IService; +import com.zzyl.nursing.dto.NursingPlanDto; +import com.zzyl.nursing.vo.NursingPlanVo; + +/** + * 护理计划Service接口 + * + * @author alexis + * @date 2024-12-30 + */ +public interface INursingPlanService extends IService +{ + /** + * 查询护理计划 + * + * @param id 护理计划主键 + * @return 护理计划 + */ + public NursingPlanVo selectNursingPlanById(Long id); + + /** + * 查询护理计划列表 + * + * @param nursingPlan 护理计划 + * @return 护理计划集合 + */ + public List selectNursingPlanList(NursingPlan nursingPlan); + + /** + * 新增护理计划 + * + * @param nursingPlanDto 护理计划 + * @return 结果 + */ + public int insertNursingPlan(NursingPlanDto nursingPlanDto); + + /** + * 修改护理计划 + * + * @param nursingPlanDto 护理计划 + * @return 结果 + */ + public int updateNursingPlan(NursingPlanDto nursingPlanDto); + + /** + * 批量删除护理计划 + * + * @param ids 需要删除的护理计划主键集合 + * @return 结果 + */ + public int deleteNursingPlanByIds(Long[] ids); + + /** + * 删除护理计划信息 + * + * @param id 护理计划主键 + * @return 结果 + */ + public int deleteNursingPlanById(Long id); + + /** + * 查询所有护理计划 + * @return 护理计划列表 + */ + List getAllNursingPlans(); +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/INursingProjectService.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/INursingProjectService.java new file mode 100644 index 0000000..8bde1a3 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/INursingProjectService.java @@ -0,0 +1,70 @@ +package com.zzyl.nursing.service; + +import java.util.List; +import com.zzyl.nursing.domain.NursingProject; +import com.baomidou.mybatisplus.extension.service.IService; +import com.zzyl.nursing.vo.NursingProjectVo; + +/** + * 护理项目Service接口 + * + * @author alexis + * @date 2024-12-30 + */ +public interface INursingProjectService extends IService +{ + /** + * 查询护理项目 + * + * @param id 护理项目主键 + * @return 护理项目 + */ + public NursingProject selectNursingProjectById(Long id); + + /** + * 查询护理项目列表 + * + * @param nursingProject 护理项目 + * @return 护理项目集合 + */ + public List selectNursingProjectList(NursingProject nursingProject); + + /** + * 新增护理项目 + * + * @param nursingProject 护理项目 + * @return 结果 + */ + public int insertNursingProject(NursingProject nursingProject); + + /** + * 修改护理项目 + * + * @param nursingProject 护理项目 + * @return 结果 + */ + public int updateNursingProject(NursingProject nursingProject); + + /** + * 批量删除护理项目 + * + * @param ids 需要删除的护理项目主键集合 + * @return 结果 + */ + public int deleteNursingProjectByIds(Long[] ids); + + /** + * 删除护理项目信息 + * + * @param id 护理项目主键 + * @return 结果 + */ + public int deleteNursingProjectById(Long id); + + /** + * 查询所有护理项目VO列表 + * @return 结果 + */ + List getAllProjects(); + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/INursingTaskService.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/INursingTaskService.java new file mode 100644 index 0000000..a4561b0 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/INursingTaskService.java @@ -0,0 +1,102 @@ +package com.zzyl.nursing.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.zzyl.common.core.domain.R; +import com.zzyl.common.core.page.TableDataInfo; +import com.zzyl.nursing.domain.Elder; +import com.zzyl.nursing.domain.NursingTask; +import com.zzyl.nursing.dto.NursingTaskCancelDto; +import com.zzyl.nursing.dto.NursingTaskDoDto; +import com.zzyl.nursing.dto.NursingTaskDto; +import com.zzyl.nursing.dto.NursingTaskUpdateDto; +import com.zzyl.nursing.vo.NursingTaskVo; + +import java.util.List; + +/** + * 护理任务Service接口 + * + * @author ruoyi + * @date 2024-09-27 + */ +public interface INursingTaskService extends IService +{ + /** + * 查询护理任务 + * + * @param id 护理任务主键 + * @return 护理任务 + */ + public NursingTaskVo selectNursingTaskById(Long id); + + /** + * 查询护理任务列表 + * + * @param nursingTask 护理任务 + * @return 护理任务集合 + */ + public List selectNursingTaskList(NursingTask nursingTask); + + /** + * 新增护理任务 + * + * @param nursingTask 护理任务 + * @return 结果 + */ + public int insertNursingTask(NursingTask nursingTask); + + /** + * 修改护理任务 + * + * @param nursingTask 护理任务 + * @return 结果 + */ + public int updateNursingTask(NursingTask nursingTask); + + /** + * 批量删除护理任务 + * + * @param ids 需要删除的护理任务主键集合 + * @return 结果 + */ + public int deleteNursingTaskByIds(Long[] ids); + + /** + * 删除护理任务信息 + * + * @param id 护理任务主键 + * @return 结果 + */ + public int deleteNursingTaskById(Long id); + + /** + * 生成护理任务 + * @param elder + */ + void createMonthTask(Elder elder); + + /** + * 查询护理任务列表 + * @param nursingTaskDto 查询参数 + * @return 结果 + */ + TableDataInfo list(NursingTaskDto nursingTaskDto); + + /** + * 取消任务 + * @param nursingTaskCancelDto 取消任务原因dto + */ + void cancel(NursingTaskCancelDto nursingTaskCancelDto); + + /** + * 执行任务 + * @param nursingTaskDoDto 执行任务dto + */ + void doTask(NursingTaskDoDto nursingTaskDoDto); + + /** + * 更新时间 + * @param nursingTaskUpdateDto + */ + void updateTime(NursingTaskUpdateDto nursingTaskUpdateDto); +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/IRoomService.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/IRoomService.java new file mode 100644 index 0000000..c8471fc --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/IRoomService.java @@ -0,0 +1,87 @@ +package com.zzyl.nursing.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.zzyl.nursing.domain.Room; +import com.zzyl.nursing.vo.RoomVo; + +import java.util.List; + +/** + * 房间Service接口 + * + * @author ruoyi + * @date 2024-04-26 + */ +public interface IRoomService extends IService { + /** + * 查询房间 + * + * @param id 房间ID + * @return 房间 + */ + public Room selectRoomById(Long id); + + /** + * 查询房间列表 + * + * @param room 房间 + * @return 房间集合 + */ + public List selectRoomList(Room room); + + /** + * 新增房间 + * + * @param room 房间 + * @return 结果 + */ + public int insertRoom(Room room); + + /** + * 修改房间 + * + * @param room 房间 + * @return 结果 + */ + public int updateRoom(Room room); + + /** + * 批量删除房间 + * + * @param ids 需要删除的房间ID集合 + * @return 结果 + */ + public int deleteRoomByIds(Long[] ids); + + /** + * 根据楼层 id 获取房间 视图对象列表 + * + * @param floorId 楼层id + * @return + */ + List getRoomsByFloorId(Long floorId); + + /** + * 获取所有房间(负责老人) + * + * @param floorId + * @return + */ + List getRoomsWithNurByFloorId(Long floorId); + + /** + * 根据房间id查询房间 数据 + * + * @return: + * @param: + */ + RoomVo getRoomPriceByRoomId(Long id); + + /** + * 获取房间中的智能设备及数据 + * + * @return: + * @param: + */ + List getRoomsWithDeviceByFloorId(Long floorId); +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/IRoomTypeService.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/IRoomTypeService.java new file mode 100644 index 0000000..30938da --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/IRoomTypeService.java @@ -0,0 +1,70 @@ +package com.zzyl.nursing.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.zzyl.nursing.domain.RoomType; + +import java.util.List; + +/** + * 房型Service接口 + * + * @author ruoyi + * @date 2024-04-26 + */ +public interface IRoomTypeService extends IService +{ + /** + * 查询房型 + * + * @param id 房型主键 + * @return 房型 + */ + public RoomType selectRoomTypeById(Long id); + + /** + * 查询房型列表 + * + * @param roomType 房型 + * @return 房型集合 + */ + public List selectRoomTypeList(RoomType roomType); + + /** + * 新增房型 + * + * @param roomType 房型 + * @return 结果 + */ + public int insertRoomType(RoomType roomType); + + /** + * 修改房型 + * + * @param roomType 房型 + * @return 结果 + */ + public int updateRoomType(RoomType roomType); + + /** + * 批量删除房型 + * + * @param ids 需要删除的房型主键集合 + * @return 结果 + */ + public int deleteRoomTypeByIds(Long[] ids); + + /** + * 删除房型信息 + * + * @param id 房型主键 + * @return 结果 + */ + public int deleteRoomTypeById(Long id); + + /** + * 按照状态查询房间类型 + * @param status + * @return + */ + List findRoomTypeListByStatus(Integer status); +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/IWeChatService.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/IWeChatService.java new file mode 100644 index 0000000..c0f6e73 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/IWeChatService.java @@ -0,0 +1,28 @@ +package com.zzyl.nursing.service; + +/** + * 微信小程序服务接口 + * + * @author Zhy + * @version 1.0 + * @date 2025-03-03 17:05 + */ +public interface IWeChatService { + + /** + * 获取微信小程序的openid + * + * @return: + * @param: + */ + String getOpenId(String code); + + /** + * 获取微信小程序的手机号码 + * + * @return: + * @param: + */ + String getPhoneNumber(String detailCode); + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/AlertDataServiceImpl.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/AlertDataServiceImpl.java new file mode 100644 index 0000000..44c813b --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/AlertDataServiceImpl.java @@ -0,0 +1,121 @@ +package com.zzyl.nursing.service.impl; + +import java.util.Arrays; +import java.util.List; + +import cn.hutool.core.bean.BeanUtil; +import com.zzyl.common.utils.SecurityUtils; +import com.zzyl.nursing.dto.AlertDataPageQueryDto; +import com.zzyl.nursing.dto.HandleAlertDataDto; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import com.zzyl.nursing.mapper.AlertDataMapper; +import com.zzyl.nursing.domain.AlertData; +import com.zzyl.nursing.service.IAlertDataService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; + +/** + * 报警数据Service业务层处理 + * + * @author Zhy + * @date 2025-03-11 + */ +@Service +@RequiredArgsConstructor +public class AlertDataServiceImpl extends ServiceImpl implements IAlertDataService { + + private final AlertDataMapper alertDataMapper; + + /** + * 查询报警数据 + * + * @param id 报警数据主键 + * @return 报警数据 + */ + @Override + public AlertData selectAlertDataById(Long id) { + return alertDataMapper.selectById(id); + } + + /** + * 查询报警数据列表 + * + * @param alertData 报警数据 + * @return 报警数据 + */ + @Override + public List selectAlertDataList(AlertData alertData) { + return alertDataMapper.selectAlertDataList(alertData); + } + + /** + * 新增报警数据 + * + * @param alertData 报警数据 + * @return 结果 + */ + @Override + public int insertAlertData(AlertData alertData) { + return alertDataMapper.insert(alertData); + } + + /** + * 修改报警数据 + * + * @param alertData 报警数据 + * @return 结果 + */ + @Override + public int updateAlertData(AlertData alertData) { + return alertDataMapper.updateById(alertData); + } + + /** + * 批量删除报警数据 + * + * @param ids 需要删除的报警数据主键 + * @return 结果 + */ + @Override + public int deleteAlertDataByIds(Long[] ids) { + return alertDataMapper.deleteBatchIds(Arrays.asList(ids)); + } + + /** + * 删除报警数据信息 + * + * @param id 报警数据主键 + * @return 结果 + */ + @Override + public int deleteAlertDataById(Long id) { + return alertDataMapper.deleteById(id); + } + + /** + * 查询报警数据列表 + * + * @return: + * @param: + */ + @Override + public List pageQueryAlertData(AlertDataPageQueryDto alertDataPageQueryDto) { + return alertDataMapper.pageQueryAlertData(alertDataPageQueryDto); + } + + /** + * 处理设备报警数据 + * + * @return: + * @param: + */ + @Override + public void handleAlertData(HandleAlertDataDto handleAlertDataDto) { + AlertData alertData = BeanUtil.toBean(handleAlertDataDto, AlertData.class); + alertData.setStatus(1); + alertData.setProcessorName(SecurityUtils.getUsername()); + alertData.setProcessorId(SecurityUtils.getUserId()); + + updateById(alertData); + } +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/AlertRuleServiceImpl.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/AlertRuleServiceImpl.java new file mode 100644 index 0000000..0b6d6c3 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/AlertRuleServiceImpl.java @@ -0,0 +1,326 @@ +package com.zzyl.nursing.service.impl; + +import cn.hutool.core.date.LocalDateTimeUtil; +import cn.hutool.core.util.StrUtil; + +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.temporal.ChronoUnit; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ObjUtil; +import cn.hutool.json.JSONUtil; +import com.zzyl.common.constant.CacheConstants; +import com.zzyl.nursing.config.WebSocketServer; +import com.zzyl.nursing.domain.AlertData; +import com.zzyl.nursing.domain.DeviceData; +import com.zzyl.nursing.mapper.DeviceMapper; +import com.zzyl.nursing.service.IAlertDataService; +import com.zzyl.nursing.vo.AlertNotifyVo; +import com.zzyl.system.mapper.SysUserRoleMapper; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Service; +import com.zzyl.nursing.mapper.AlertRuleMapper; +import com.zzyl.nursing.domain.AlertRule; +import com.zzyl.nursing.service.IAlertRuleService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; + +/** + * 报警规则Service业务层处理 + * + * @author Zhy + * @date 2025-03-11 + */ +@Service +@RequiredArgsConstructor +@Slf4j +public class AlertRuleServiceImpl extends ServiceImpl implements IAlertRuleService { + + private final AlertRuleMapper alertRuleMapper; + private final RedisTemplate redisTemplate; + private final DeviceMapper deviceMapper; + private final SysUserRoleMapper sysUserRoleMapper; + private final IAlertDataService alertDataService; + private final WebSocketServer webSocketServer; + + /** + * 查询报警规则 + * + * @param id 报警规则主键 + * @return 报警规则 + */ + @Override + public AlertRule selectAlertRuleById(Long id) { + return alertRuleMapper.selectById(id); + } + + /** + * 查询报警规则列表 + * + * @param alertRule 报警规则 + * @return 报警规则 + */ + @Override + public List selectAlertRuleList(AlertRule alertRule) { + return alertRuleMapper.selectAlertRuleList(alertRule); + } + + /** + * 新增报警规则 + * + * @param alertRule 报警规则 + * @return 结果 + */ + @Override + public int insertAlertRule(AlertRule alertRule) { + return alertRuleMapper.insert(alertRule); + } + + /** + * 修改报警规则 + * + * @param alertRule 报警规则 + * @return 结果 + */ + @Override + public int updateAlertRule(AlertRule alertRule) { + return alertRuleMapper.updateById(alertRule); + } + + /** + * 批量删除报警规则 + * + * @param ids 需要删除的报警规则主键 + * @return 结果 + */ + @Override + public int deleteAlertRuleByIds(Long[] ids) { + return alertRuleMapper.deleteBatchIds(Arrays.asList(ids)); + } + + /** + * 删除报警规则信息 + * + * @param id 报警规则主键 + * @return 结果 + */ + @Override + public int deleteAlertRuleById(Long id) { + return alertRuleMapper.deleteById(id); + } + + /** + * 新增报警规则 + * + * @return: + * @param: + */ + @Override + public void createAlertRule(AlertRule alertRule) { + + } + + /** + * 设备数据异常告警 + * + * @return: + * @param: + */ + @Override + public void alertFilter() { + // log.warn("触发报警规则,记录数据---->"); + + // 1.查询所有规则 + long count = this.lambdaQuery().eq(AlertRule::getStatus, 1).count(); + if (count <= 0) { + return; + } + // 2.查询所有设备上报的数据 + List values = redisTemplate.opsForHash().values(CacheConstants.IOT_DEVICE_LAST_DATA); + if (CollUtil.isEmpty(values)) { + return; + } + // 遍历 values,把每个设备上报的数据合并到一起 + List deviceDataList = new ArrayList<>(); + values.forEach(v -> deviceDataList.addAll(JSONUtil.toList(JSONUtil.toJsonStr(v), DeviceData.class))); + + LocalDateTime now = LocalDateTime.now(); + // 3.根据报警规则进行过滤 + deviceDataList.forEach(d -> alertFilterEveryData(d, now)); + + } + + /** + * 过滤每一条数据。去匹配规则,是否满足,满足插入到数据库 + * + * @param data 上报数据 + */ + private void alertFilterEveryData(DeviceData data, LocalDateTime now) { + // 1.判断上报数据和现在时间是否超过了1分钟,如果超过,则认为该数据没有匹配价值 + LocalDateTime alarmTime = data.getAlarmTime(); + long between = LocalDateTimeUtil.between(alarmTime, now, ChronoUnit.SECONDS); + if (between > 60) { + return; + } + // 2.查询当前产品下所有设备指定物理型且开启的规则 + List allDeviceRules = this.lambdaQuery() + .eq(AlertRule::getProductKey, data.getProductKey()) + .eq(AlertRule::getFunctionId, data.getFunctionId()) + .eq(AlertRule::getIotId, -1) + .eq(AlertRule::getStatus, 1) + .list(); + // 3.查询当前产品下指定设备指定物理型且开启的规则 + List OneDeviceRules = this.lambdaQuery() + .eq(AlertRule::getProductKey, data.getProductKey()) + .eq(AlertRule::getFunctionId, data.getFunctionId()) + .eq(AlertRule::getIotId, data.getIotId()) + .eq(AlertRule::getStatus, 1) + .list(); + // 4.合并一起 + Collection allRules = CollUtil.addAll(allDeviceRules, OneDeviceRules); + if (CollUtil.isEmpty(allRules)) { + return; + } + // 5.遍历规则,进行匹配 + allRules.forEach(rule -> dataFilterRule(rule, data)); + } + + /** + * 根据规则匹配数据 + * + * @param rule 规则 + * @param data 上报数据 + */ + private void dataFilterRule(AlertRule rule, DeviceData data) { + // 1.判断是否在生效时间内 + String[] split = rule.getAlertEffectivePeriod().split("~"); + LocalTime startTime = LocalTime.parse(split[0]); + LocalTime endTime = LocalTime.parse(split[1]); + // 数据上报的时间 + LocalTime localTime = data.getAlarmTime().toLocalTime(); + // 如果上报的时间不在生效时段内,则结束请求 + if (localTime.isBefore(startTime) || localTime.isAfter(endTime)) { + return; + } + + // 2.校验数据是否达到阈值 + // 统计次数的key + String aggCountKey = CacheConstants.ALERT_TRIGGER_COUNT_PREFIX + + rule.getId() + + data.getIotId() + + ":" + + data.getFunctionId(); + Double value = Double.valueOf(data.getDataValue()); + Double ruleValue = rule.getValue(); + int result = Double.compare(value, ruleValue); + // 0相等 1:value大 -1:ruleValue大 + if ((">=".equals(rule.getOperator()) && result < 0) || ("<".equals(rule.getOperator()) && result >= 0)) { + redisTemplate.delete(aggCountKey); + return; + } + + // 3.判断是否在沉默时间内,如果在,则本次报警不发送 + String aggSilentKey = CacheConstants.ALERT_SILENT_PREFIX + + rule.getId() + + data.getIotId() + + ":" + + data.getFunctionId(); + if (ObjUtil.isNotNull(redisTemplate.opsForValue().get(aggSilentKey))) { + return; + } + + // 4.判断报警次数 是否等于持续周期 + Integer aggCount = (Integer) redisTemplate.opsForValue().get(aggCountKey); + aggCount = ObjUtil.isNull(aggCount) ? 1 : aggCount + 1; + if (ObjUtil.notEqual(aggCount, rule.getDuration())) { + redisTemplate.opsForValue().set(aggCountKey, aggCount); + return; + } + + // 5.校验通过,删除报警次数,增加沉默周期 + redisTemplate.delete(aggCountKey); + redisTemplate.opsForValue().set(aggSilentKey, 1, rule.getAlertSilentPeriod(), TimeUnit.MINUTES); + + // 6.查询老人报警数据对应的护理人员 + List userIds = new ArrayList<>(); + if (rule.getAlertDataType().equals(0)) { + // 是老人报警类型 + if (data.getLocationType().equals(0)) { + // 是随身设备 + userIds = deviceMapper.selectNursingIdsByIotIdWithElder(data.getIotId()); + } else if (data.getLocationType().equals(1) && data.getPhysicalLocationType().equals(2)) { + // 固定设备 + userIds = deviceMapper.selectNursingIdsByIotIdWithBed(data.getIotId()); + } + } else { + // 设备异常数据 + // 7.查询设备报警数据对应的维修人员 + userIds = sysUserRoleMapper.selectUserIdByRoleName("维修工"); + } + + userIds = userIds.stream().filter(Objects::nonNull).collect(Collectors.toList()); + // 通知管理员 + List adminIds = sysUserRoleMapper.selectUserIdByRoleName("超级管理员"); + Collection allUserIds = CollUtil.addAll(adminIds, userIds).stream().distinct().collect(Collectors.toList()); + // 8.保存数据 + List alertData = insertBatch(allUserIds, rule, data); + + // 9. Websocket推送消息 + websocketNotify(alertData.get(0), rule, allUserIds); + } + + + /** + * websocket推送消息 + * + * @param alertData 报警数据 + * @param rule 规则 + * @param allUserIds 通知人列表 + */ + private void websocketNotify(AlertData alertData, AlertRule rule, Collection allUserIds) { + + // 属性拷贝 + AlertNotifyVo alertNotifyVo = BeanUtil.toBean(alertData, AlertNotifyVo.class); + alertNotifyVo.setFunctionName(rule.getFunctionName()); + alertNotifyVo.setAlertDataType(rule.getAlertDataType()); + alertNotifyVo.setNotifyType(1); + // 向指定的人推送消息 + webSocketServer.sendMessageToConsumer(alertNotifyVo, allUserIds); + } + + /** + * 批量保存报警规则数据 + * + * @param userIds 通知人列表 + * @param rule 规则 + * @param data 上报数据 + */ + private List insertBatch(Collection userIds, AlertRule rule, DeviceData data) { + List dataList = userIds.stream().map(userId -> { + AlertData alertData = BeanUtil.toBean(data, AlertData.class); + alertData.setId(null); + alertData.setAlertRuleId(rule.getId()); + String alertReason = StrUtil.format("{}{}{},持续了{}周期报警", + rule.getFunctionName(), + rule.getOperator(), + rule.getValue(), + rule.getDuration() + ); + alertData.setAlertReason(alertReason); + alertData.setType(rule.getAlertDataType()); + alertData.setStatus(0); + alertData.setUserId(userId); + return alertData; + }).collect(Collectors.toList()); + alertDataService.saveBatch(dataList); + + return dataList; + } + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/BedServiceImpl.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/BedServiceImpl.java new file mode 100644 index 0000000..7c97673 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/BedServiceImpl.java @@ -0,0 +1,96 @@ +package com.zzyl.nursing.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.zzyl.nursing.domain.Bed; +import com.zzyl.nursing.mapper.BedMapper; +import com.zzyl.nursing.service.IBedService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.List; + +/** + * 床位Service业务层处理 + * + * @author ruoyi + * @date 2024-04-26 + */ +@Service +public class BedServiceImpl extends ServiceImpl implements IBedService +{ + @Autowired + private BedMapper bedMapper; + + /** + * 查询床位 + * + * @param id 床位主键 + * @return 床位 + */ + @Override + public Bed selectBedById(Long id) + { + return getById(id); + } + + /** + * 查询床位列表 + * + * @param bed 床位 + * @return 床位 + */ + @Override + public List selectBedList(Bed bed) + { + return bedMapper.selectBedList(bed); + } + + /** + * 新增床位 + * + * @param bed 床位 + * @return 结果 + */ + @Override + public int insertBed(Bed bed) + { + return save(bed) ? 1 : 0; + } + + /** + * 修改床位 + * + * @param bed 床位 + * @return 结果 + */ + @Override + public int updateBed(Bed bed) + { + return updateById(bed) ? 1 : 0; + } + + /** + * 批量删除床位 + * + * @param ids 需要删除的床位主键 + * @return 结果 + */ + @Override + public int deleteBedByIds(Long[] ids) + { + return removeByIds(Arrays.asList(ids)) ? 1 : 0; + } + + /** + * 删除床位信息 + * + * @param id 床位主键 + * @return 结果 + */ + @Override + public int deleteBedById(Long id) + { + return removeById(id) ? 1 : 0; + } +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/CheckInConfigServiceImpl.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/CheckInConfigServiceImpl.java new file mode 100644 index 0000000..faba022 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/CheckInConfigServiceImpl.java @@ -0,0 +1,95 @@ +package com.zzyl.nursing.service.impl; + +import java.util.Arrays; +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.zzyl.nursing.mapper.CheckInConfigMapper; +import com.zzyl.nursing.domain.CheckInConfig; +import com.zzyl.nursing.service.ICheckInConfigService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; + +/** + * 入住配置表Service业务层处理 + * + * @Author: Zhy + * @Date: 2025-02-25 + */ +@Service +public class CheckInConfigServiceImpl extends ServiceImpl implements ICheckInConfigService +{ + @Autowired + private CheckInConfigMapper checkInConfigMapper; + + /** + * 查询入住配置表 + * + * @param id 入住配置表主键 + * @return 入住配置表 + */ + @Override + public CheckInConfig selectCheckInConfigById(Long id) + { + return checkInConfigMapper.selectById(id); + } + + /** + * 查询入住配置表列表 + * + * @param checkInConfig 入住配置表 + * @return 入住配置表 + */ + @Override + public List selectCheckInConfigList(CheckInConfig checkInConfig) + { + return checkInConfigMapper.selectCheckInConfigList(checkInConfig); + } + + /** + * 新增入住配置表 + * + * @param checkInConfig 入住配置表 + * @return 结果 + */ + @Override + public int insertCheckInConfig(CheckInConfig checkInConfig) + { + return checkInConfigMapper.insert(checkInConfig); + } + + /** + * 修改入住配置表 + * + * @param checkInConfig 入住配置表 + * @return 结果 + */ + @Override + public int updateCheckInConfig(CheckInConfig checkInConfig) + { + return checkInConfigMapper.updateById(checkInConfig); + } + + /** + * 批量删除入住配置表 + * + * @param ids 需要删除的入住配置表主键 + * @return 结果 + */ + @Override + public int deleteCheckInConfigByIds(Long[] ids) + { + return checkInConfigMapper.deleteBatchIds(Arrays.asList(ids)); + } + + /** + * 删除入住配置表信息 + * + * @param id 入住配置表主键 + * @return 结果 + */ + @Override + public int deleteCheckInConfigById(Long id) + { + return checkInConfigMapper.deleteById(id); + } +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/CheckInServiceImpl.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/CheckInServiceImpl.java new file mode 100644 index 0000000..98a78fa --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/CheckInServiceImpl.java @@ -0,0 +1,295 @@ +package com.zzyl.nursing.service.impl; + +import cn.hutool.core.util.IdcardUtil; +import com.alibaba.fastjson2.JSON; + +import java.util.Arrays; +import java.util.List; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.zzyl.common.exception.base.BaseException; +import com.zzyl.nursing.domain.*; +import com.zzyl.nursing.dto.CheckInApplyDto; +import com.zzyl.nursing.dto.CheckInElderDto; +import com.zzyl.nursing.dto.ElderFamilyDto; +import com.zzyl.nursing.mapper.*; +import com.zzyl.nursing.util.CodeGeneratorUtil; +import com.zzyl.nursing.vo.CheckInConfigVo; +import com.zzyl.nursing.vo.CheckInDetailVo; +import com.zzyl.nursing.vo.CheckInElderVo; +import com.zzyl.nursing.vo.ElderFamilyVo; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import com.zzyl.nursing.service.ICheckInService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.transaction.annotation.Transactional; + +/** + * 入住表Service业务层处理 + * + * @Author: Zhy + * @Date: 2025-02-25 + */ +@Service +@RequiredArgsConstructor +public class CheckInServiceImpl extends ServiceImpl implements ICheckInService { + + private final CheckInMapper checkInMapper; + private final ElderMapper elderMapper; + private final BedMapper bedMapper; + private final ContractMapper contractMapper; + private final CheckInConfigMapper checkInConfigMapper; + + private static int sort = 0; + + /** + * 查询入住表 + * + * @param id 入住表主键 + * @return 入住表 + */ + @Override + public CheckIn selectCheckInById(Long id) { + return checkInMapper.selectById(id); + } + + /** + * 查询入住表列表 + * + * @param checkIn 入住表 + * @return 入住表 + */ + @Override + public List selectCheckInList(CheckIn checkIn) { + return checkInMapper.selectCheckInList(checkIn); + } + + /** + * 新增入住表 + * + * @param checkIn 入住表 + * @return 结果 + */ + @Override + public int insertCheckIn(CheckIn checkIn) { + return checkInMapper.insert(checkIn); + } + + /** + * 修改入住表 + * + * @param checkIn 入住表 + * @return 结果 + */ + @Override + public int updateCheckIn(CheckIn checkIn) { + return checkInMapper.updateById(checkIn); + } + + /** + * 批量删除入住表 + * + * @param ids 需要删除的入住表主键 + * @return 结果 + */ + @Override + public int deleteCheckInByIds(Long[] ids) { + return checkInMapper.deleteBatchIds(Arrays.asList(ids)); + } + + /** + * 删除入住表信息 + * + * @param id 入住表主键 + * @return 结果 + */ + @Override + public int deleteCheckInById(Long id) { + return checkInMapper.deleteById(id); + } + + /** + * 申请入住 + * + * @return: + * @param: + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void apply(CheckInApplyDto checkInApplyDto) { + // 1. 检验老人是否已经入住 + Elder elder = checkElderIsEnable(checkInApplyDto.getCheckInElderDto().getIdCardNo()); + + // 2. 检验床位状态是否已经入住 + Bed bed = checkBedIsEnable(checkInApplyDto.getCheckInConfigDto().getBedId()); + + // 3. 新增或更新老人信息 + elder = updateOrInsertElder(elder, bed, checkInApplyDto.getCheckInElderDto()); + + // 4. 新增签约办理 + addContract(elder, checkInApplyDto); + + // 5. 新增入住信息 + Long checkId = addCheckIn(elder, checkInApplyDto); + + // 6. 新增入住配置 + addCheckInConfig(checkId, checkInApplyDto); + } + + /** + * 新增入住配置 + * + * @return: + * @param: checkId 入住id + * @param: checkInApplyDto 入住申请信息 + */ + private void addCheckInConfig(Long checkId, CheckInApplyDto checkInApplyDto) { + CheckInConfig checkInConfig = BeanUtil.toBean(checkInApplyDto.getCheckInConfigDto(), CheckInConfig.class); + checkInConfig.setCheckInId(checkId); + checkInConfig.setSortOrder(sort++); + + checkInConfigMapper.insert(checkInConfig); + } + + /** + * 新增入住信息 + * + * @return: Long 入住id + * @param: elder 老人信息 + * @param: checkInApplyDto 入住申请信息 + */ + private Long addCheckIn(Elder elder, CheckInApplyDto checkInApplyDto) { + CheckIn checkIn = BeanUtil.toBean(checkInApplyDto.getCheckInConfigDto(), CheckIn.class); + checkIn.setElderName(elder.getName()); + checkIn.setElderId(elder.getId()); + checkIn.setIdCardNo(elder.getIdCardNo()); + checkIn.setBedNumber(elder.getBedNumber()); + checkIn.setStatus(0); + checkIn.setSortOrder(sort++); + + // 家属信息 + List elderFamilyDtoList = checkInApplyDto.getElderFamilyDtoList(); + checkIn.setRemark(JSON.toJSONString(elderFamilyDtoList)); + + save(checkIn); + + return checkIn.getId(); + } + + /** + * 新增签约办理 + * + * @return: + * @param: + */ + private void addContract(Elder elder, CheckInApplyDto checkInApplyDto) { + Contract contract = BeanUtil.toBean(checkInApplyDto.getCheckInContractDto(), Contract.class); + contract.setElderId(elder.getId().intValue()); + contract.setContractNumber(CodeGeneratorUtil.generateContractNumber()); + contract.setElderName(elder.getName()); + contract.setStartDate(checkInApplyDto.getCheckInConfigDto().getStartDate()); + contract.setEndDate(checkInApplyDto.getCheckInConfigDto().getEndDate()); + contract.setStatus(0); + contract.setSortOrder(sort++); + contract.setRemark(""); + + contractMapper.insert(contract); + } + + /** + * 新增或更新老人信息 + * + * @return: Elder 老人信息 + * @param: checkInElderDto 前端传来的老人信息 + * @param: bed 床位信息 + */ + private Elder updateOrInsertElder(Elder elder, Bed bed, CheckInElderDto checkInElderDto) { + if (ObjectUtil.isNotNull(elder)) { + BeanUtil.copyProperties(checkInElderDto, elder); + } else { + elder = BeanUtil.toBean(checkInElderDto, Elder.class); + } + elder.setStatus(1); + elder.setBedNumber(bed.getBedNumber()); + elder.setBedId(bed.getId()); + + if (ObjectUtil.isNull(elder.getId())) { + // 新增 + elderMapper.insert(elder); + } else { + // 更新 + elderMapper.updateById(elder); + } + return elder; + } + + /** + * 检验床位状态是否已经入住 + * + * @return: Bed 床位信息 + * @param: bedId 床位id + * @param: i 床位状态 + */ + private Bed checkBedIsEnable(Long bedId) { + Bed bed = bedMapper.selectBedById(bedId); + bed.setBedStatus(1); + bedMapper.updateById(bed); + return bed; + } + + /** + * 检验老人是否已经入住 + * + * @return: Elder 老人信息 + * @param: idCardNo 身份证号 + */ + private Elder checkElderIsEnable(String idCardNo) { + Elder elder = elderMapper.selectOne(new LambdaQueryWrapper().eq(Elder::getIdCardNo, idCardNo)); + if (ObjectUtil.isNotNull(elder) && elder.getStatus().equals(1)) { + throw new BaseException("该老人已经入住,请勿重复申请"); + } + return elder; + } + + /** + * 入住详情 + * + * @return: + * @param: id 入住id + */ + @Override + @Transactional(rollbackFor = Exception.class) + public CheckInDetailVo getCheckInInfo(Long id) { + // 1. 查询入住配置信息 + CheckInConfigVo checkInConfigVo = checkInMapper.selectCheckInInfoById(id); + + // 2. 封装家属信息 + List elderFamilyVoList = null; + if (ObjectUtil.isNotNull(checkInConfigVo.getRemark())) { + String remark = checkInConfigVo.getRemark(); + // 使用 parseArray 方法并指定泛型类型 + elderFamilyVoList = JSON.parseArray(remark, ElderFamilyVo.class); + } + + // 3. 查询合同信息 + Contract contract = contractMapper.selectContractByElderId(id); + + // 4. 查询老人信息 + CheckInElderVo checkInElderVo = elderMapper.selectByCheckId(id); + // 根据老人出生日期计算年龄 + int age = IdcardUtil.getAgeByIdCard(checkInElderVo.getIdCardNo()); + checkInElderVo.setAge(age); + + // 5. 封装入住详情信息 + CheckInDetailVo checkInDetailVo = new CheckInDetailVo(); + checkInDetailVo.setCheckInConfigVo(checkInConfigVo); + checkInDetailVo.setElderFamilyVoList(elderFamilyVoList); + checkInDetailVo.setContract(contract); + checkInDetailVo.setCheckInElderVo(checkInElderVo); + + return checkInDetailVo; + } + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/ContractServiceImpl.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/ContractServiceImpl.java new file mode 100644 index 0000000..b442faa --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/ContractServiceImpl.java @@ -0,0 +1,128 @@ +package com.zzyl.nursing.service.impl; + +import java.time.LocalDateTime; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import cn.hutool.core.bean.BeanException; +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.zzyl.nursing.mapper.ContractMapper; +import com.zzyl.nursing.domain.Contract; +import com.zzyl.nursing.service.IContractService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.transaction.annotation.Transactional; + +/** + * 合同表Service业务层处理 + * + * @Author: Zhy + * @Date: 2025-02-25 + */ +@Service +public class ContractServiceImpl extends ServiceImpl implements IContractService { + @Autowired + private ContractMapper contractMapper; + + /** + * 查询合同表 + * + * @param id 合同表主键 + * @return 合同表 + */ + @Override + public Contract selectContractById(Integer id) { + return contractMapper.selectById(id); + } + + /** + * 查询合同表列表 + * + * @param contract 合同表 + * @return 合同表 + */ + @Override + public List selectContractList(Contract contract) { + return contractMapper.selectContractList(contract); + } + + /** + * 新增合同表 + * + * @param contract 合同表 + * @return 结果 + */ + @Override + public int insertContract(Contract contract) { + return contractMapper.insert(contract); + } + + /** + * 修改合同表 + * + * @param contract 合同表 + * @return 结果 + */ + @Override + public int updateContract(Contract contract) { + return contractMapper.updateById(contract); + } + + /** + * 批量删除合同表 + * + * @param ids 需要删除的合同表主键 + * @return 结果 + */ + @Override + public int deleteContractByIds(Integer[] ids) { + return contractMapper.deleteBatchIds(Arrays.asList(ids)); + } + + /** + * 删除合同表信息 + * + * @param id 合同表主键 + * @return 结果 + */ + @Override + public int deleteContractById(Integer id) { + return contractMapper.deleteById(id); + } + + /** + * 更新合同状态 + * + * @return: + * @param: + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int updateContractStatus() { + // 当前时间大于开始时间,小于结束时间,状态为0,则更新状态为1 + LocalDateTime now = LocalDateTime.now(); + List notStartList = this.lambdaQuery() + .eq(Contract::getStatus, 0) + .le(Contract::getStartDate, now) + .ge(Contract::getEndDate, now) + .list(); + notStartList .forEach(v -> v.setStatus(1)); + boolean flag = this.updateBatchById(notStartList ); + if (!flag && ObjectUtil.isNotEmpty(notStartList )) { + throw new BeanException("将合同状态由 “未生效” 更新为 “已生效” 失败!"); + } + + // 当前时间大于结束时间,状态为1,则更新状态为3 + List endList = this.lambdaQuery().eq(Contract::getStatus, 1).lt(Contract::getEndDate, now).list(); + endList.forEach(v -> v.setStatus(3)); + flag = this.updateBatchById(endList); + if (!flag && ObjectUtil.isNotEmpty(endList)) { + throw new BeanException("将合同状态由 “已生效” 更新为 “已失效” 失败!"); + } + + return 1; + } +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/DeviceDataServiceImpl.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/DeviceDataServiceImpl.java new file mode 100644 index 0000000..b2e45a7 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/DeviceDataServiceImpl.java @@ -0,0 +1,207 @@ +package com.zzyl.nursing.service.impl; + +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; + +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import cn.hutool.core.date.LocalDateTimeUtil; +import cn.hutool.core.util.ObjUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.zzyl.common.constant.CacheConstants; +import com.zzyl.common.core.page.TableDataInfo; +import com.zzyl.common.exception.base.BaseException; +import com.zzyl.nursing.domain.Device; +import com.zzyl.nursing.dto.DeviceDataPageReqDto; +import com.zzyl.nursing.mapper.DeviceMapper; +import com.zzyl.nursing.vo.IotMsgNotifyData; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Service; +import com.zzyl.nursing.mapper.DeviceDataMapper; +import com.zzyl.nursing.domain.DeviceData; +import com.zzyl.nursing.service.IDeviceDataService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.transaction.annotation.Transactional; + +/** + * 设备数据Service业务层处理 + * + * @author Zhy + * @date 2025-03-08 + */ +@Service +@RequiredArgsConstructor +@Slf4j +public class DeviceDataServiceImpl extends ServiceImpl implements IDeviceDataService { + + private final DeviceDataMapper deviceDataMapper; + private final DeviceMapper deviceMapper; + private final RedisTemplate redisTemplate; + + /** + * 查询设备数据 + * + * @param id 设备数据主键 + * @return 设备数据 + */ + @Override + public DeviceData selectDeviceDataById(Long id) { + return deviceDataMapper.selectById(id); + } + + /** + * 查询设备数据列表 + * + * @param deviceData 设备数据 + * @return 设备数据 + */ + @Override + public List selectDeviceDataList(DeviceData deviceData) { + return deviceDataMapper.selectDeviceDataList(deviceData); + } + + /** + * 新增设备数据 + * + * @param deviceData 设备数据 + * @return 结果 + */ + @Override + public int insertDeviceData(DeviceData deviceData) { + return deviceDataMapper.insert(deviceData); + } + + /** + * 修改设备数据 + * + * @param deviceData 设备数据 + * @return 结果 + */ + @Override + public int updateDeviceData(DeviceData deviceData) { + return deviceDataMapper.updateById(deviceData); + } + + /** + * 批量删除设备数据 + * + * @param ids 需要删除的设备数据主键 + * @return 结果 + */ + @Override + public int deleteDeviceDataByIds(Long[] ids) { + return deviceDataMapper.deleteBatchIds(Arrays.asList(ids)); + } + + /** + * 删除设备数据信息 + * + * @param id 设备数据主键 + * @return 结果 + */ + @Override + public int deleteDeviceDataById(Long id) { + return deviceDataMapper.deleteById(id); + } + + /** + * 批量保存数据 + * + * @param iotMsgNotifyData 设备数据集合 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void batchInsertDeviceData(IotMsgNotifyData iotMsgNotifyData) { + // 1. 根据设备 ID 查询本地设备是否存在 + String deviceId = iotMsgNotifyData.getHeader().getDeviceId(); + Device device = deviceMapper.selectOne(new LambdaQueryWrapper().eq(Device::getIotId, deviceId)); + if (ObjUtil.isEmpty(device)) { + throw new BaseException("设备不存在"); + } + + // 2. 从设备实体中获取数据,赋值到设备数据实体中 + + // 3. 把 IOT 获取到的设备赋值到设备数据实体中 + // 存放设备数据列表 + List deviceDataList = new ArrayList<>(); + + iotMsgNotifyData.getBody().getServices().forEach(item -> { + LocalDateTime activeTime = LocalDateTimeUtil.parse(item.getEventTime(), "yyyyMMdd'T'HHmmss'Z'"); + // 日期时区转换 + LocalDateTime alarmTime = activeTime.atZone(ZoneId.from(ZoneOffset.UTC)).withZoneSameInstant(ZoneId.of( + "Asia/Shanghai")).toLocalDateTime(); + + // 遍历该设备中的每个属性 + item.getProperties().forEach((key, value) -> { + DeviceData deviceData = DeviceData.builder() + .iotId(deviceId) + .deviceName(device.getDeviceName()) + .productKey(device.getProductKey()) + .productName(device.getProductName()) + .functionId(key) + .accessLocation(device.getRemark()) + .locationType(device.getLocationType()) + .physicalLocationType(device.getPhysicalLocationType()) + .deviceDescription(device.getDeviceDescription()) + .dataValue(value.toString()) + .alarmTime(alarmTime) + .build(); + + deviceDataList.add(deviceData); + }); + }); + + // 4. 批量保存设备数据 + if (!saveBatch(deviceDataList)) { + throw new BaseException("批量保存设备数据失败"); + } + + // 5. 将最新数据保存在 Redis 中 + try { + redisTemplate.opsForHash().put(CacheConstants.IOT_DEVICE_LAST_DATA, deviceId, JSONUtil.toJsonStr(deviceDataList)); + } catch (Exception e) { + log.warn("保存设备最新数据到 Redis 失败"); + } + } + + /** + * 分页查询设备数据列表 + * + * @return: + * @param: + */ + @Override + public TableDataInfo selectDeviceDataPageList(DeviceDataPageReqDto deviceDataPageReqDto) { + + Page page = new Page<>(deviceDataPageReqDto.getPageNum(), deviceDataPageReqDto.getPageSize()); + + this.lambdaQuery().eq( + StrUtil.isNotBlank(deviceDataPageReqDto.getDeviceName()), + DeviceData::getDeviceName, + deviceDataPageReqDto.getDeviceName() + ).eq( + StrUtil.isNotBlank(deviceDataPageReqDto.getFunctionId()), + DeviceData::getFunctionId, + deviceDataPageReqDto.getFunctionId() + ).between((ObjUtil.isNotEmpty(deviceDataPageReqDto.getStartTime()) && + ObjUtil.isNotEmpty(deviceDataPageReqDto.getEndTime()) + ), DeviceData::getAlarmTime, deviceDataPageReqDto.getStartTime(), deviceDataPageReqDto.getEndTime()).page(page); + + TableDataInfo tableDataInfo = new TableDataInfo<>(); + tableDataInfo.setTotal(page.getTotal()); + tableDataInfo.setRows(page.getRecords()); + tableDataInfo.setCode(200); + tableDataInfo.setMsg("获取设备数据成功"); + + return tableDataInfo; + } + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/DeviceServiceImpl.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/DeviceServiceImpl.java new file mode 100644 index 0000000..2694952 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/DeviceServiceImpl.java @@ -0,0 +1,344 @@ +package com.zzyl.nursing.service.impl; + +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.util.*; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.LocalDateTimeUtil; +import cn.hutool.core.util.ObjUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.huaweicloud.sdk.iotda.v5.IoTDAClient; +import com.huaweicloud.sdk.iotda.v5.model.*; +import com.zzyl.common.constant.CacheConstants; +import com.zzyl.common.exception.base.BaseException; +import com.zzyl.nursing.dto.DeviceDto; +import com.zzyl.nursing.vo.DeviceDetailVo; +import com.zzyl.nursing.vo.DeviceReportDataVo; +import com.zzyl.nursing.vo.ProductVo; +import lombok.RequiredArgsConstructor; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Service; +import com.zzyl.nursing.mapper.DeviceMapper; +import com.zzyl.nursing.domain.Device; +import com.zzyl.nursing.service.IDeviceService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; + +/** + * 设备Service业务层处理 + * + * @author Zhy + * @date 2025-03-06 + */ +@Service +@RequiredArgsConstructor +public class DeviceServiceImpl extends ServiceImpl implements IDeviceService { + + private final DeviceMapper deviceMapper; + private final IoTDAClient client; + private final RedisTemplate redisTemplate; + + /** + * 查询设备列表 + * + * @param device 设备 + * @return 设备 + */ + @Override + public List selectDeviceList(Device device) { + return deviceMapper.selectDeviceList(device); + } + + /** + * 从物联网平台同步产品列表 + * + * @return: + * @param: + */ + @Override + public void syncProductList() { + ListProductsRequest listProductsRequest = new ListProductsRequest(); + listProductsRequest.setLimit(50); + ListProductsResponse response = client.listProducts(listProductsRequest); + + if (ObjUtil.isNotEmpty(response.getProducts())) { + // 存入 Redis 缓存 + redisTemplate.opsForValue().set(CacheConstants.IOT_ALL_PRODUCT, JSONUtil.toJsonStr(response.getProducts())); + } + } + + /** + * 查询所有产品列表 + * + * @return: + * @param: + */ + @Override + public List allProduct() { + String jsonStr = redisTemplate.opsForValue().get(CacheConstants.IOT_ALL_PRODUCT); + if (ObjUtil.isEmpty(jsonStr)) { + // 返回一个空列表 + return Collections.emptyList(); + } + return JSONUtil.toList(jsonStr, ProductVo.class); + } + + /** + * 注册设备 + * + * @return: + * @param: + */ + @Override + public void registerProduct(DeviceDto deviceDto) { + // 1. 检查设备名字是否重复 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + long count = count(queryWrapper.eq(Device::getDeviceName, deviceDto.getDeviceName())); + if (count > 0) { + throw new BaseException("设备名字重复"); + } + + // 2. 检查设备标识是否重复 + queryWrapper = new LambdaQueryWrapper<>(); + count = count(queryWrapper.eq(Device::getNodeId, deviceDto.getNodeId())); + if (count > 0) { + throw new BaseException("设备标识重复"); + } + + // 3. 检查同一个位置是否绑定的相同的产品 + queryWrapper = new LambdaQueryWrapper<>(); + count = count(queryWrapper.eq(Device::getBindingLocation, deviceDto.getBindingLocation()) + .eq(Device::getProductKey, deviceDto.getProductKey()) + .eq(Device::getLocationType, deviceDto.getLocationType())); + if (count > 0) { + throw new BaseException("同一个位置不能绑定同类型的产品"); + } + + // 补全实体 + String secret = UUID.randomUUID().toString().replace("-", ""); + String iotId = UUID.randomUUID().toString().replace("-", ""); + + // 4. 注册设备到 IOT 平台 + // 封装发送的请求 + AddDeviceRequest request = new AddDeviceRequest(); + // 封装请求体 + AddDevice body = new AddDevice(); + body.withProductId(deviceDto.getProductKey()); + body.withDeviceName(deviceDto.getDeviceName()); + body.withNodeId(deviceDto.getNodeId()); + body.withDeviceId(iotId); + // 将封装的请求体信息放入请求中 + request.withBody(body); + // 创建认证信息 + AuthInfo authInfo = new AuthInfo(); + // 设置秘钥 + authInfo.withSecret(secret); + // 将认证信息放入请求中 + body.setAuthInfo(authInfo); + AddDeviceResponse response; + try { + response = client.addDevice(request); + } catch (Exception e) { + throw new BaseException("IOT平台注册设备失败," + e.getMessage()); + } + + // 5. 保存设备信息到数据库 + Device device = BeanUtil.toBean(deviceDto, Device.class); + device.setSecret(secret); + device.setIotId(iotId); + try { + save(device); + } catch (Exception e) { + // 删除 IOT 平台注册的设备 + // TODO + + throw new BaseException("新增设备信息失败,请联系管理员"); + } + } + + /** + * 查询设备详细数据 + * + * @return: + * @param: + */ + @Override + public DeviceDetailVo queryDeviceDetail(String iotId) { + // 1. 查询数据库中是否有数据 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + Device device = getOne(queryWrapper.eq(Device::getIotId, iotId)); + if (ObjUtil.isEmpty(device)) { + return null; + } + + // 2. 查询 IOT + ShowDeviceRequest request = new ShowDeviceRequest(); + request.withDeviceId(iotId); + ShowDeviceResponse response; + try { + response = client.showDevice(request); + if (!Objects.equals(response.getHttpStatusCode(), 200)) { + throw new BaseException("查询设备详细数据失败"); + } + } catch (Exception e) { + throw new BaseException("查询设备详细数据失败," + e.getMessage()); + } + + // 3. 整合属性 + DeviceDetailVo deviceDetailVo = BeanUtil.toBean(device, DeviceDetailVo.class); + deviceDetailVo.setDeviceStatus(response.getStatus()); + String activeTimeStr = response.getActiveTime(); + if (ObjUtil.isNotEmpty(activeTimeStr)) { + LocalDateTime activeTime = LocalDateTimeUtil.parse(activeTimeStr, DatePattern.UTC_MS_PATTERN); + // 日期时区转换 + activeTime = activeTime.atZone(ZoneId.from(ZoneOffset.UTC)) + .withZoneSameInstant(ZoneId.of("Asia/Shanghai")) + .toLocalDateTime(); + deviceDetailVo.setActiveTime(activeTime); + } + + return deviceDetailVo; + } + + /** + * 查询设备上报数据 + * + * @return: + * @param: + */ + @Override + public List queryDeviceReportData(String iotId) { + // 1. 查询 IOT 中的数据 + ShowDeviceShadowRequest request = new ShowDeviceShadowRequest(); + request.withDeviceId(iotId); + ShowDeviceShadowResponse response; + try { + response = client.showDeviceShadow(request); + if (!ObjUtil.equals(response.getHttpStatusCode(), 200)) { + throw new BaseException("从 IOT 平台查询设备上报数据失败"); + } + } catch (Exception e) { + throw new BaseException("从 IOT 平台查询设备上报数据失败"); + } + + // 2. 解析数据 + List shadowList = response.getShadow(); + if (ObjUtil.isEmpty(shadowList)) { + return new ArrayList<>(); + } + DeviceShadowData shadowData = shadowList.get(0); + if (ObjUtil.isEmpty(shadowData)) { + return new ArrayList<>(); + } + // 3. 处理时间 + String eventTime = shadowData.getReported().getEventTime(); + LocalDateTime activeTime = LocalDateTimeUtil.parse(eventTime, "yyyyMMdd'T'HHmmss'Z'"); + // 日期时区转换 + activeTime = activeTime.atZone(ZoneId.from(ZoneOffset.UTC)) + .withZoneSameInstant(ZoneId.of("Asia/Shanghai")) + .toLocalDateTime(); + + // 4. 封装结果 + List deviceVo = new ArrayList<>(); + Object properties = shadowData.getReported().getProperties(); + if (properties instanceof Map) { + Map map = (Map) properties; + LocalDateTime finalActiveTime = activeTime; + map.forEach((k, v) -> { + deviceVo.add(new DeviceReportDataVo(k, finalActiveTime, v.toString())); + }); + } + + return deviceVo; + } + + /** + * 更新设备数据 + * + * @return: + * @param: + */ + @Override + public void updateDevice(Device device) { + // 1. 更新 IOT + UpdateDeviceRequest request = new UpdateDeviceRequest(); + request.withDeviceId(device.getIotId()); + UpdateDevice body = new UpdateDevice(); + body.withDeviceName(device.getDeviceName()); + // 将封装的请求体信息放入请求中 + request.withBody(body); + + UpdateDeviceResponse response; + try { + response = client.updateDevice(request); + if (!ObjUtil.equals(response.getHttpStatusCode(), 200)) { + throw new BaseException("IOT 更新设备信息失败"); + } + } catch (Exception e) { + throw new BaseException("IOT 更新设备信息失败"); + } + + // 2. 更新数据库 + try { + updateById(device); + } catch (Exception e) { + // TODO + // 回滚 IOT 更新 + + throw new BaseException("数据库更新设备信息失败"); + } + } + + /** + * 删除设备 + * + * @return: + * @param: + */ + @Override + public void deleteDeviceByIotId(String iotId) { + // 1. 删除 IOT 上的设备 + DeleteDeviceRequest request = new DeleteDeviceRequest(); + request.withDeviceId(iotId); + try { + client.deleteDevice(request); + } catch (Exception e) { + throw new BaseException("IOT 删除设备失败"); + } + + // 2. 删除数据库中的设备信息 + try { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(Device::getIotId, iotId); + remove(queryWrapper); + } catch (Exception e) { + throw new BaseException("数据库删除设备信息失败"); + } + } + + /** + * 获取产品对应的服务信息 + * + * @return: + * @param: + */ + @Override + public List queryProductByProductKey(String productKey) { + ShowProductRequest request = new ShowProductRequest(); + request.withProductId(productKey); + try { + ShowProductResponse response = client.showProduct(request); + List serviceList = response.getServiceCapabilities(); + if(ObjUtil.isEmpty(serviceList)){ + return List.of(); + } + return serviceList; + } catch (Exception e) { + throw new BaseException("查询产品服务信息失败"); + } + } + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/ElderServiceImpl.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/ElderServiceImpl.java new file mode 100644 index 0000000..6322c0b --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/ElderServiceImpl.java @@ -0,0 +1,125 @@ +package com.zzyl.nursing.service.impl; + +import java.util.Arrays; +import java.util.List; + +import cn.hutool.core.util.ObjUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.zzyl.common.core.page.TableDataInfo; +import com.zzyl.nursing.dto.ElderPageQuery; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import com.zzyl.nursing.mapper.ElderMapper; +import com.zzyl.nursing.domain.Elder; +import com.zzyl.nursing.service.IElderService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; + +/** + * 老人Service业务层处理 + * + * @Author: Zhy + * @Date: 2025-02-25 + */ +@Service +@RequiredArgsConstructor +public class ElderServiceImpl extends ServiceImpl implements IElderService { + + private final ElderMapper elderMapper; + + /** + * 查询老人 + * + * @param id 老人主键 + * @return 老人 + */ + @Override + public Elder selectElderById(Long id) { + return elderMapper.selectById(id); + } + + /** + * 查询老人列表 + * + * @param elder 老人 + * @return 老人 + */ + @Override + public List selectElderList(Elder elder) { + return elderMapper.selectElderList(elder); + } + + /** + * 新增老人 + * + * @param elder 老人 + * @return 结果 + */ + @Override + public int insertElder(Elder elder) { + return elderMapper.insert(elder); + } + + /** + * 修改老人 + * + * @param elder 老人 + * @return 结果 + */ + @Override + public int updateElder(Elder elder) { + return elderMapper.updateById(elder); + } + + /** + * 批量删除老人 + * + * @param ids 需要删除的老人主键 + * @return 结果 + */ + @Override + public int deleteElderByIds(Long[] ids) { + return elderMapper.deleteBatchIds(Arrays.asList(ids)); + } + + /** + * 删除老人信息 + * + * @param id 老人主键 + * @return 结果 + */ + @Override + public int deleteElderById(Long id) { + return elderMapper.deleteById(id); + } + + /** + * 查询已经入住的老人列表 + * + * @return: + * @param: + */ + @Override + public TableDataInfo pageQuery(ElderPageQuery elderPageQuery) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + + // 创建分页对象 + Page page = new Page<>(elderPageQuery.getPageNum(), elderPageQuery.getPageSize()); + + // 安装状态查询 + queryWrapper.select(Elder::getId, Elder::getName, Elder::getIdCardNo, Elder::getBedNumber); + // 状态查询 + if (ObjUtil.isNotEmpty(elderPageQuery.getName())) { + queryWrapper.like(Elder::getName, elderPageQuery.getName()); + } + if (ObjUtil.isNotEmpty(elderPageQuery.getIdCardNo())) { + queryWrapper.like(Elder::getIdCardNo, elderPageQuery.getIdCardNo()); + } + + + // 执行分页 + page = page(page, queryWrapper); + + return new TableDataInfo(page.getRecords(), (int) page.getTotal()); + } +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/FamilyMemberServiceImpl.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/FamilyMemberServiceImpl.java new file mode 100644 index 0000000..4bd703c --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/FamilyMemberServiceImpl.java @@ -0,0 +1,334 @@ +package com.zzyl.nursing.service.impl; + +import java.time.*; +import java.time.format.DateTimeFormatter; +import java.time.temporal.TemporalField; +import java.util.*; +import java.util.stream.Collectors; + +import cn.hutool.core.collection.ListUtil; +import cn.hutool.core.util.ObjUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.zzyl.common.constant.CacheConstants; +import com.zzyl.common.exception.base.BaseException; +import com.zzyl.common.utils.UserThreadLocal; +import com.zzyl.framework.web.service.TokenService; +import com.zzyl.nursing.domain.*; +import com.zzyl.nursing.dto.ElderDto; +import com.zzyl.nursing.dto.QueryDevicePropertyDto; +import com.zzyl.nursing.dto.UserLoginRequestDto; +import com.zzyl.nursing.mapper.*; +import com.zzyl.nursing.service.IWeChatService; +import com.zzyl.nursing.vo.DevicePropertyVo; +import com.zzyl.nursing.vo.FamilyMemberElderVo; +import com.zzyl.nursing.vo.LoginVo; +import lombok.RequiredArgsConstructor; +import org.apache.xmlbeans.impl.xb.xsdschema.NamespaceList; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Service; +import com.zzyl.nursing.service.IFamilyMemberService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.transaction.annotation.Transactional; + +/** + * 老人家属Service业务层处理 + * + * @author Zhy + * @date 2025-03-03 + */ +@Service +@RequiredArgsConstructor +public class FamilyMemberServiceImpl extends ServiceImpl implements IFamilyMemberService { + + private final FamilyMemberMapper familyMemberMapper; + private final IWeChatService weChatService; + private final TokenService tokenService; + private final ElderServiceImpl elderServiceImpl; + private final FamilyMemberElderMapper familyMemberElderMapper; + private final ElderMapper elderMapper; + private final BedMapper bedMapper; + private final DeviceServiceImpl deviceServiceImpl; + private final RedisTemplate redisTemplate; + private final DeviceDataMapper deviceDataMapper; + + static List DEFAULT_NICKNAME_PREFIX = ListUtil.of("生活更美好", + "大桔大利", + "日富一日", + "好柿开花", + "柿柿如意", + "一椰暴富", + "大柚所为", + "杨梅吐气", + "天生荔枝" + ); + + /** + * 查询老人家属 + * + * @param id 老人家属主键 + * @return 老人家属 + */ + @Override + public FamilyMember selectFamilyMemberById(Long id) { + return familyMemberMapper.selectById(id); + } + + /** + * 查询老人家属列表 + * + * @param familyMember 老人家属 + * @return 老人家属 + */ + @Override + public List selectFamilyMemberList(FamilyMember familyMember) { + return familyMemberMapper.selectFamilyMemberList(familyMember); + } + + /** + * 新增老人家属 + * + * @param familyMember 老人家属 + * @return 结果 + */ + @Override + public int insertFamilyMember(FamilyMember familyMember) { + return familyMemberMapper.insert(familyMember); + } + + /** + * 修改老人家属 + * + * @param familyMember 老人家属 + * @return 结果 + */ + @Override + public int updateFamilyMember(FamilyMember familyMember) { + return familyMemberMapper.updateById(familyMember); + } + + /** + * 批量删除老人家属 + * + * @param ids 需要删除的老人家属主键 + * @return 结果 + */ + @Override + public int deleteFamilyMemberByIds(Long[] ids) { + return familyMemberMapper.deleteBatchIds(Arrays.asList(ids)); + } + + /** + * 删除老人家属信息 + * + * @param id 老人家属主键 + * @return 结果 + */ + @Override + public int deleteFamilyMemberById(Long id) { + return familyMemberMapper.deleteById(id); + } + + /** + * 小程序登录 + * + * @return: + * @param: + */ + @Override + @Transactional(rollbackFor = Exception.class) + public LoginVo login(UserLoginRequestDto userLoginRequestDto) { + // 1. 根据 opendId 查询用户信息 + String openId = weChatService.getOpenId(userLoginRequestDto.getCode()); + if (ObjUtil.isEmpty(openId)) { + throw new BaseException("获取 openId 失败"); + } + // 2. 获取用户信息 + FamilyMember member = this.lambdaQuery().eq(FamilyMember::getOpenId, openId).one(); + // 3. 如果为空,则创建用户 + if (ObjUtil.isNull(member)) { + member = new FamilyMember(); + member.setOpenId(openId); + } + // 4. 获取手机号 + String phoneNumber = weChatService.getPhoneNumber(userLoginRequestDto.getPhoneCode()); + // 5. 新增或更新用户信息 + insertOrUpdate(member, phoneNumber); + // 6. 生成 token + Map claims = new HashMap<>(); + claims.put("id", member.getId()); + claims.put("nickName", member.getName()); + String token = tokenService.createToken(claims); + // 7. 封装数据并返回 + LoginVo loginVo = new LoginVo(); + loginVo.setToken(token); + loginVo.setNickName(member.getName()); + + return loginVo; + } + + @Override + public void addMember(ElderDto elderDto) { + // 校验老人姓名和身份证号是否为入住老人 + Elder elder = elderServiceImpl.lambdaQuery() + .eq(Elder::getName, elderDto.getName()) + .eq(Elder::getIdCardNo, elderDto.getIdCard()) + .one(); + if (ObjectUtil.isNull(elder)) { + throw new BaseException("该老人未入住,请先入住"); + } + + // 新增老人家属绑定信息 + elderDto.setCreateTime(new Date()); + elderDto.setFamilyMemberId(UserThreadLocal.getUserId()); + elderDto.setElderId(elder.getId()); + familyMemberElderMapper.insert(elderDto); + } + + @Override + public List getMyElder() { + return familyMemberElderMapper.getMyElder(UserThreadLocal.getUserId()); + } + + @Override + public List listByPage(Integer pageNum, Integer pageSize) { + Integer startNum = (pageNum - 1) * pageSize; + List elderList = familyMemberElderMapper.getMyElderPage(UserThreadLocal.getUserId(), startNum, pageSize); + List familyMemberElderVoList = new ArrayList<>(); + for (ElderDto elder : elderList) { + FamilyMemberElderVo familyMemberElderVo = new FamilyMemberElderVo(); + familyMemberElderVo.setMid(elder.getId()); + familyMemberElderVo.setMremark(elder.getRemark()); + Long elderId = elder.getElderId(); + familyMemberElderVo.setElderId(elderId); + Elder elderInfo = elderMapper.selectElderById(elderId); + familyMemberElderVo.setName(elderInfo.getName()); + familyMemberElderVo.setImage(elderInfo.getImage()); + familyMemberElderVo.setBedNumber(elderInfo.getBedNumber()); + String typeName = bedMapper.getRoomTypeNameByBedId(elderInfo.getBedId()); + familyMemberElderVo.setTypeName(typeName); + Device device = deviceServiceImpl.lambdaQuery() + .eq(Device::getBindingLocation, elderInfo.getId()) + .eq(Device::getPhysicalLocationType, -1).one(); + if (ObjectUtil.isNotNull(device)) { + familyMemberElderVo.setIotId(device.getIotId()); + familyMemberElderVo.setDeviceName(device.getDeviceName()); + familyMemberElderVo.setProductKey(device.getProductKey()); + } + familyMemberElderVoList.add(familyMemberElderVo); + } + return familyMemberElderVoList; + } + + @Override + public DevicePropertyVo queryDevicePropertyStatus(QueryDevicePropertyDto queryDevicePropertyDto) { + DevicePropertyVo devicePropertyVo = new DevicePropertyVo(); + DevicePropertyList devicePropertyList = new DevicePropertyList(); + List propertyStatusInfoList = new ArrayList<>(); + Device device = deviceServiceImpl.lambdaQuery() + .eq(Device::getProductKey, queryDevicePropertyDto.getProductKey()) + .eq(Device::getDeviceName, queryDevicePropertyDto.getDeviceName()).one(); + // List deviceDataList = (List)redisTemplate.opsForHash().get("iot:device_last_data", device.getIotId()); + List deviceDataList = (List)redisTemplate.opsForHash().get(CacheConstants.IOT_DEVICE_LAST_DATA, device.getIotId()); + for (DeviceData deviceData : deviceDataList) { + PropertyStatusInfo propertyStatusInfo = new PropertyStatusInfo(); + propertyStatusInfo.setDataType("double"); + propertyStatusInfo.setIdentifier(deviceData.getFunctionId()); + propertyStatusInfo.setName(deviceData.getFunctionId()); + LocalDateTime alarmTime = deviceData.getAlarmTime(); + // alarmTime转为Long + propertyStatusInfo.setTime(deviceData.getAlarmTime() + .atZone(ZoneOffset.UTC) + .toInstant() + .toEpochMilli()); + propertyStatusInfo.setValue(Double.parseDouble(deviceData.getDataValue())); + propertyStatusInfoList.add(propertyStatusInfo); + } + devicePropertyList.setPropertyStatusInfo(propertyStatusInfoList); + devicePropertyVo.setList(devicePropertyList); + return devicePropertyVo; + } + + @Override + public List> queryDeviceDataListByDay(String functionId, String iotId, Long startTime, Long endTime) { + LocalDateTime startTimeDate = LocalDateTime.ofInstant(Instant.ofEpochMilli(startTime), ZoneOffset.UTC).plusHours(8); + LocalDateTime endTimeDate = LocalDateTime.ofInstant(Instant.ofEpochMilli(endTime), ZoneOffset.UTC).plusHours(8); + List> list = deviceDataMapper.queryDeviceDataListByDay(functionId, iotId, startTimeDate, endTimeDate); + List> newList = new ArrayList<>(24); + for (int i = 0; i <= 23; i++) { + String tailTime = ":00"; + String time; + if (i < 10) { + time = "0" + i + tailTime; + } else { + time = i + tailTime; + } + for (Map map : list) { + if (time.equals(map.get("dateTime"))) { + newList.add(map); + break; + } + } + Map map = new HashMap<>(); + map.put("dateTime", time); + map.put("dataValue", 0.0); + if (newList.size() != i + 1) { + newList.add(map); + } + } + return newList; + } + + @Override + public List> queryDeviceDataListByWeek(String functionId, String iotId, Long startTime, Long endTime) { + LocalDateTime startTimeDate = LocalDateTime.ofInstant(Instant.ofEpochMilli(startTime), ZoneOffset.UTC).plusHours(8); + LocalDateTime endTimeDate = LocalDateTime.ofInstant(Instant.ofEpochMilli(endTime), ZoneOffset.UTC).plusHours(8); + List> mapList = deviceDataMapper.queryDeviceDataListByWeek(functionId, iotId, startTimeDate, endTimeDate); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM.dd"); + List> newList = new ArrayList<>(7); + for (int i = 0; i < 7; i++) { + String dateTime = startTimeDate.format(formatter); + for (Map map : mapList) { + if (dateTime.equals(map.get("dateTime"))) { + newList.add(map); + break; + } + } + if (newList.size() != i + 1) { + Map map = new HashMap<>(); + map.put("dateTime", dateTime); + map.put("dataValue", 0.0); + newList.add(map); + } + startTimeDate = startTimeDate.plusDays(1); + } + return newList; + } + + /** + * 新增或更新用户信息 + * + * @return: + * @param: + */ + private void insertOrUpdate(FamilyMember member, String phoneNumber) { + // 更新手机号 + if (!StrUtil.equals(member.getPhone(), phoneNumber)) { + member.setPhone(phoneNumber); + } + + // 更新用户 + if (ObjUtil.isNotNull(member.getId())) { + this.updateById(member); + return; + } + + // 新增用户 + String nickName = DEFAULT_NICKNAME_PREFIX.get((int) (Math.random() * DEFAULT_NICKNAME_PREFIX.size())) + StrUtil.sub(member.getPhone(), + 7, + member.getPhone().length() + ); + member.setName(nickName); + this.save(member); + } +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/FloorServiceImpl.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/FloorServiceImpl.java new file mode 100644 index 0000000..6db7207 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/FloorServiceImpl.java @@ -0,0 +1,121 @@ +package com.zzyl.nursing.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.zzyl.nursing.domain.Floor; +import com.zzyl.nursing.mapper.FloorMapper; +import com.zzyl.nursing.service.IFloorService; +import com.zzyl.nursing.vo.FloorVo; +import com.zzyl.nursing.vo.TreeVo; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.List; + +/** + * 楼层Service业务层处理 + * + * @author ruoyi + * @date 2024-04-26 + */ +@Service +public class FloorServiceImpl extends ServiceImpl implements IFloorService { + @Autowired + private FloorMapper floorMapper; + + /** + * 查询楼层 + * + * @param id 楼层主键 + * @return 楼层 + */ + @Override + public Floor selectFloorById(Long id) { + return getById(id); + } + + /** + * 新增楼层 + * + * @param floor 楼层 + * @return 结果 + */ + @Override + public int insertFloor(Floor floor) { + return save(floor) ? 1 : 0; + } + + /** + * 修改楼层 + * + * @param floor 楼层 + * @return 结果 + */ + @Override + public int updateFloor(Floor floor) { + return updateById(floor) ? 1 : 0; + } + + /** + * 批量删除楼层 + * + * @param ids 需要删除的楼层主键 + * @return 结果 + */ + @Override + public int deleteFloorByIds(Long[] ids) { + return removeByIds(Arrays.asList(ids)) ? 1 : 0; + } + + /** + * 删除楼层信息 + * + * @param id 楼层主键 + * @return 结果 + */ + @Override + public int deleteFloorById(Long id) { + return removeById(id) ? 1 : 0; + } + + /** + * 查询所有楼层(负责老人) + */ + @Override + public List selectAllByNur() { + return floorMapper.selectAllByNur(); + } + + /** + * 获取所有楼层所有房间中的空床位 + * + * @return: + * @param: + */ + @Override + public List getRoomAndBedByBedStatus(Integer status) { + return floorMapper.selectRoomAndBedByBedStatus(status); + } + + /** + * 获取所有装有智能设备的楼层 + * + * @return: + * @param: + */ + @Override + public List getAllFloorsWithDevice() { + return floorMapper.getAllFloorsWithDevice(); + } + + /** + * 获取所有楼层 + * + * @return: + * @param: + */ + @Override + public List getRoomAndBed() { + return floorMapper.selectRoomAndBed(); + } +} \ No newline at end of file diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/HealthAssessmentServiceImpl.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/HealthAssessmentServiceImpl.java new file mode 100644 index 0000000..ee3475f --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/HealthAssessmentServiceImpl.java @@ -0,0 +1,278 @@ +package com.zzyl.nursing.service.impl; + +import java.time.LocalDateTime; + +import cn.hutool.json.JSONUtil; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import cn.hutool.core.util.StrUtil; +import com.zzyl.common.ai.AIModelInvoker; +import com.zzyl.common.constant.CacheConstants; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.exception.base.BaseException; +import com.zzyl.common.utils.PDFUtil; +import com.zzyl.common.utils.file.FileUtils; +import com.zzyl.nursing.dto.HealthAssessmentDto; +import com.zzyl.nursing.util.IDCardUtils; +import com.zzyl.nursing.vo.health.HealthReportVo; +import com.zzyl.oss.AliyunOssUtils; +import lombok.RequiredArgsConstructor; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Service; +import com.zzyl.nursing.mapper.HealthAssessmentMapper; +import com.zzyl.nursing.domain.HealthAssessment; +import com.zzyl.nursing.service.IHealthAssessmentService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.web.multipart.MultipartFile; + +/** + * 健康评估Service业务层处理 + * + * @author Zhy + * @Date: 2025-02-28 + */ +@Service +@RequiredArgsConstructor +public class HealthAssessmentServiceImpl extends ServiceImpl implements IHealthAssessmentService { + private final HealthAssessmentMapper healthAssessmentMapper; + private final AliyunOssUtils aliyunOssUtils; + private final RedisTemplate redisTemplate; + + private final AIModelInvoker aiModelInvoker; + + /** + * 查询健康评估 + * + * @param id 健康评估主键 + * @return 健康评估 + */ + @Override + public HealthAssessment selectHealthAssessmentById(Long id) { + return healthAssessmentMapper.selectById(id); + } + + /** + * 查询健康评估列表 + * + * @param healthAssessment 健康评估 + * @return 健康评估 + */ + @Override + public List selectHealthAssessmentList(HealthAssessment healthAssessment) { + return healthAssessmentMapper.selectHealthAssessmentList(healthAssessment); + } + + /** + * 新增健康评估 + * + * @param healthAssessmentDto 健康评估 + * @return 结果 + */ + @Override + public Long insertHealthAssessment(HealthAssessmentDto healthAssessmentDto) { + // 1. 组装 prompt + String prompt = getPrompt(healthAssessmentDto); + + // 2. 调用千帆大模型来分析数据 + String result = aiModelInvoker.qianfanInvoker(prompt); + + HealthReportVo healthReportVo = JSONUtil.toBean(result, HealthReportVo.class); + // 3. 整合数据 + HealthAssessment healthAssessment = integrate(healthReportVo, healthAssessmentDto); + + // 4. 保存数据库 + healthAssessmentMapper.insert(healthAssessment); + + return healthAssessment.getId(); + } + + /** + * 整合数据 + * + * @return: + * @param: + */ + private HealthAssessment integrate(HealthReportVo healthReportVo, HealthAssessmentDto healthAssessmentDto) { + HealthAssessment healthAssessment = new HealthAssessment(); + + String idCard = healthAssessmentDto.getIdCard(); + // 健康评分 + double healthScore = healthReportVo.getHealthAssessment().getHealthIndex(); + + healthAssessment.setElderName(healthAssessmentDto.getElderName()); + healthAssessment.setIdCard(idCard); + healthAssessment.setBirthDate(IDCardUtils.getBirthDateByIdCard(idCard)); + healthAssessment.setAge(IDCardUtils.getAgeByIdCard(idCard)); + healthAssessment.setGender(IDCardUtils.getGenderFromIdCard(idCard)); + healthAssessment.setHealthScore(String.valueOf(healthScore)); + healthAssessment.setRiskLevel(healthReportVo.getHealthAssessment().getRiskLevel()); + healthAssessment.setSuggestionForAdmission(healthScore >= 60 ? 0 : 1); + healthAssessment.setNursingLevelName(getNursingLevelName(healthScore)); + healthAssessment.setAdmissionStatus(1); + healthAssessment.setTotalCheckDate(healthReportVo.getTotalCheckDate()); + healthAssessment.setPhysicalExamInstitution(healthAssessmentDto.getPhysicalExamInstitution()); + healthAssessment.setPhysicalReportUrl(healthAssessmentDto.getPhysicalReportUrl()); + healthAssessment.setAssessmentTime(LocalDateTime.now()); + healthAssessment.setReportSummary(healthReportVo.getSummarize()); + healthAssessment.setDiseaseRisk(JSONUtil.toJsonStr(healthReportVo.getRiskDistribution())); + healthAssessment.setAbnormalAnalysis(JSONUtil.toJsonStr(healthReportVo.getAbnormalData())); + healthAssessment.setSystemScore(JSONUtil.toJsonStr(healthReportVo.getSystemScore())); + + return healthAssessment; + } + + /** + * 修改健康等级 + * + * @return: + * @param: + */ + private String getNursingLevelName(double healthScore) { + if (healthScore >= 90) { + return "一级护理等级"; + } else if (healthScore >= 80) { + return "二级护理等级"; + } else if (healthScore >= 70) { + return "三级护理等级"; + } else if (healthScore >= 60) { + return "四级护理等级"; + } else { + return ""; + } + } + + /** + * 组装 prompt + * + * @return: + * @param: healthAssessmentDto 健康评估 + */ + private String getPrompt(HealthAssessmentDto healthAssessmentDto) { + String content = redisTemplate.opsForValue().get(CacheConstants.HEALTH_REPORT_KEY + + healthAssessmentDto.getIdCard()); + + return "请以一个专业医生的视角来分析这份体检报告,报告中包含了一些异常数据,我需要您对这些数据进行解读,并给出相应的健康建议。\n" + + "体检内容如下:\n" + + content + + " \n" + + "\n" + + "要求:\n" + + "1. 提取体检报告中的“总检日期”;\n" + + "2. 通过临床医学、疾病风险评估模型和数据智能分析,给该用户的风险等级和健康指数给出结果。风险等级分为:健康、提示、风险、危险、严重危险。健康指数范围为0至100分;\n" + + "3. 根据用户身体各项指标数据,详细说明该用户各项风险等级的占比是多少,最多保留两位小数。结论格式:该用户健康占比20.00%,提示占比20.00%,风险占比20%,危险占比20%,严重危险占比20%;\n" + + "4. 对于体检报告中的异常数据,请列出(异常数据的结论、体检项目名称、检查结果、参考值、单位、异常解读、建议)这7字段。解读异常数据,解决这些数据可能代表的健康问题或风险。分析可能的原因,包括但不限于生活习惯、饮食习惯、遗传因素等。基于这些异常数据和可能的原因,请给出具体的健康建议,包括饮食调整、运动建议、生活方式改变以及是否需要进一步检查或治疗等。\n" + + "结论格式:异常数据的结论:肥胖,体检项目名称:体重指数BMI,检查结果:29.2,参考值>24,单位:-。异常解读:体重超标包括超重与肥胖。体重指数(BMI)=体重(kg)/身⾼(m)的平⽅,BMI≥24为超重,BMI≥28为肥胖;男性腰围≥90cm和⼥性腰围≥85cm为腹型肥胖。体重超标是⼀种由多因素(如遗传、进⻝油脂较多、运动少、疾病等)引起的慢性代谢性疾病,尤其是肥胖,已经被世界卫⽣组织列为导致疾病负担的⼗⼤危险因素之⼀。AI建议:采取综合措施预防和控制体重,积极改变⽣活⽅式,宜低脂、低糖、⾼纤维素膳⻝,多⻝果蔬及菌藻类⻝物,增加有氧运动。若有相关疾病(如⾎脂异常、⾼⾎压、糖尿病等)应积极治疗。\n" + + "5. 根据这个体检报告的内容,分别给人体的8大系统打分,每项满分为100分,8大系统分别为:呼吸系统、消化系统、内分泌系统、免疫系统、循环系统、泌尿系统、运动系统、感官系统\n" + + "6. 给体检报告做一个总结,总结格式:体检报告中尿蛋⽩、癌胚抗原、⾎沉、空腹⾎糖、总胆固醇、⽢油三酯、低密度脂蛋⽩胆固醇、⾎清载脂蛋⽩B、动脉硬化指数、⽩细胞、平均红细胞体积、平均⾎红蛋⽩共12项指标提示异常,尿液常规共1项指标处于临界值,⾎脂、⾎液常规、尿液常规、糖类抗原、⾎清酶类等共43项指标提示正常,综合这些临床指标和数据分析:肾脏、肝胆、⼼脑⾎管存在隐患,其中⼼脑⾎管有“⾼危”⻛险;肾脏部位有“中危”⻛险;肝胆部位有“低危”⻛险。\n" + + "\n" + + "输出要求:\n" + + "最后,将以上结果输出为JSON格式,不要包含其他的文字说明,所有的返回结果都是json,详细格式如下:\n" + + "\n" + + "{\n" + + " \"totalCheckDate\": \"YYYY-MM-DD\",\n" + + " \"healthAssessment\": {\n" + + " \"riskLevel\": \"healthy/caution/risk/danger/severeDanger\",\n" + + " \"healthIndex\": XX.XX\n" + + " },\n" + + " \"riskDistribution\": {\n" + + " \"healthy\": XX.XX,\n" + + " \"caution\": XX.XX,\n" + + " \"risk\": XX.XX,\n" + + " \"danger\": XX.XX,\n" + + " \"severeDanger\": XX.XX\n" + + " },\n" + + " \"abnormalData\": [\n" + + " {\n" + + " \"conclusion\": \"异常数据的结论\",\n" + + " \"examinationItem\": \"体检项目名称\",\n" + + " \"result\": \"检查结果\",\n" + + " \"referenceValue\": \"参考值\",\n" + + " \"unit\": \"单位\",\n" + + " \"interpret\":\"对于异常的结论进一步详细的说明\",\n" + + " \"advice\":\"针对于这一项的异常,给出一些健康的建议\"\n" + + " }\n" + + " ],\n" + + " \"systemScore\": {\n" + + " \"breathingSystem\": XX,\n" + + " \"digestiveSystem\": XX,\n" + + " \"endocrineSystem\": XX,\n" + + " \"immuneSystem\": XX,\n" + + " \"circulatorySystem\": XX,\n" + + " \"urinarySystem\": XX,\n" + + " \"motionSystem\": XX,\n" + + " \"senseSystem\": XX\n" + + " },\n" + + " \"summarize\": \"体检报告的总结\"\n" + + "}"; + } + + /** + * 修改健康评估 + * + * @param healthAssessment 健康评估 + * @return 结果 + */ + @Override + public int updateHealthAssessment(HealthAssessment healthAssessment) { + return healthAssessmentMapper.updateById(healthAssessment); + } + + /** + * 批量删除健康评估 + * + * @param ids 需要删除的健康评估主键 + * @return 结果 + */ + @Override + public int deleteHealthAssessmentByIds(Long[] ids) { + return healthAssessmentMapper.deleteBatchIds(Arrays.asList(ids)); + } + + /** + * 删除健康评估信息 + * + * @param id 健康评估主键 + * @return 结果 + */ + @Override + public int deleteHealthAssessmentById(Long id) { + return healthAssessmentMapper.deleteById(id); + } + + /** + * 体检报告上传 + * + * @return: + * @param: + */ + @Override + public AjaxResult uploadFile(String idCard, MultipartFile file) { + try { + if (StrUtil.isBlank(idCard)) { + throw new BaseException("身份证号不能为空"); + } + + // 上传文件路径 + String healthUrl = aliyunOssUtils.uploadFile(file); + + AjaxResult ajax = AjaxResult.success(); + ajax.put("healthUrl", healthUrl); + ajax.put("fileName", healthUrl); + ajax.put("newFileName", FileUtils.getName(healthUrl)); + ajax.put("originalFilename", file.getOriginalFilename()); + + // 提取报告中的内容 + String content = PDFUtil.pdfToString(file.getInputStream()); + // 存入 Redis 中 + assert content != null; + redisTemplate.opsForValue().set(CacheConstants.HEALTH_REPORT_KEY + idCard, content, 60 * 60, TimeUnit.SECONDS); + + return ajax; + } catch (Exception e) { + return AjaxResult.error(e.getMessage()); + } + } +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/MemberReservationServiceImpl.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/MemberReservationServiceImpl.java new file mode 100644 index 0000000..299c74c --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/MemberReservationServiceImpl.java @@ -0,0 +1,160 @@ +package com.zzyl.nursing.service.impl; + +import java.time.LocalDateTime; +import java.util.Arrays; +import java.util.List; + +import cn.hutool.core.date.LocalDateTimeUtil; +import cn.hutool.core.util.ObjUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.zzyl.common.utils.UserThreadLocal; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.zzyl.nursing.mapper.MemberReservationMapper; +import com.zzyl.nursing.domain.MemberReservation; +import com.zzyl.nursing.service.IMemberReservationService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.transaction.annotation.Transactional; + +/** + * 预约信息Service业务层处理 + * + * @author Zhy + * @date 2025-03-05 + */ +@Service +@RequiredArgsConstructor +public class MemberReservationServiceImpl extends ServiceImpl implements IMemberReservationService { + + private final MemberReservationMapper reservationMapper; + + /** + * 查询预约信息 + * + * @param id 预约信息主键 + * @return 预约信息 + */ + @Override + public MemberReservation selectReservationById(Long id) { + return reservationMapper.selectById(id); + } + + /** + * 查询预约信息列表 + * + * @param reservation 预约信息 + * @return 预约信息 + */ + @Override + public List selectReservationList(MemberReservation reservation) { + return reservationMapper.selectReservationList(reservation); + } + + /** + * 新增预约信息 + * + * @param memberReservation 预约信息 + */ + @Override + public void insertReservation(MemberReservation memberReservation) { + memberReservation.setStatus(0); + save(memberReservation); + } + + /** + * 修改预约信息 + * + * @param reservation 预约信息 + * @return 结果 + */ + @Override + public int updateReservation(MemberReservation reservation) { + return reservationMapper.updateById(reservation); + } + + /** + * 批量删除预约信息 + * + * @param ids 需要删除的预约信息主键 + * @return 结果 + */ + @Override + public int deleteReservationByIds(Long[] ids) { + return reservationMapper.deleteBatchIds(Arrays.asList(ids)); + } + + /** + * 删除预约信息信息 + * + * @param id 预约信息主键 + * @return 结果 + */ + @Override + public int deleteReservationById(Long id) { + return reservationMapper.deleteById(id); + } + + /** + * 查询当天取消预约数量 + * + * @return: + * @param: + */ + @Override + public Integer selectReservationCount() { + // 从ThreadLocal中获取当前登录用户ID + Long userId = UserThreadLocal.getUserId(); + + // 获取当天开始、结束时间 + long time = System.currentTimeMillis(); + // 当天 + LocalDateTime ldt = LocalDateTimeUtil.of(time); + // 当天开始时间 + LocalDateTime startTime = ldt.toLocalDate().atStartOfDay(); + // 当天结束时间 + LocalDateTime endTime = startTime.plusDays(1); + + List memberReservationList = reservationMapper.selectReservationCount(userId, + startTime, + endTime + ); + return memberReservationList.size(); + } + + /** + * 取消预约 + * + * @return: + * @param: + */ + @Override + public void updateReservationById(Long id) { + MemberReservation memberReservation = new MemberReservation(); + memberReservation.setId(id); + memberReservation.setStatus(2); + updateById(memberReservation); + } + + /** + * 定时更新预约状态 + * + * @return: + * @param: + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void updateReservationStatus() { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + List list = list(queryWrapper.eq(MemberReservation::getStatus, 0) + .le(MemberReservation::getTime, LocalDateTime.now())); + + if(ObjUtil.isEmpty(list)){ + return; + } + + list.forEach(reservation -> reservation.setStatus(3)); + + this.updateBatchById(list); + } +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/NursingElderServiceImpl.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/NursingElderServiceImpl.java new file mode 100644 index 0000000..13bae8c --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/NursingElderServiceImpl.java @@ -0,0 +1,120 @@ +package com.zzyl.nursing.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.zzyl.nursing.domain.NursingElder; +import com.zzyl.nursing.dto.NursingElderDto; +import com.zzyl.nursing.mapper.NursingElderMapper; +import com.zzyl.nursing.service.INursingElderService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * 护理员老人关联Service业务层处理 + * + * @author ruoyi + * @date 2024-05-28 + */ +@Service +public class NursingElderServiceImpl extends ServiceImpl implements INursingElderService { + + @Autowired + private NursingElderMapper nursingElderMapper; + + @Override + public Boolean setNursingElder(List nursingElderDtos) { + + +// List elderIds = nursingElderDtos.stream().map(NursingElderDto::getElderId).collect(Collectors.toList()); + //重新添加 + List list = new ArrayList<>(); + List elderIds = new ArrayList<>(); + nursingElderDtos.forEach(nursingElderDto -> { + Long elderId = nursingElderDto.getElderId(); + elderIds.add(elderId); + nursingElderDto.getNursingIds().forEach(nursingId -> { + NursingElder nursingElder = new NursingElder(); + nursingElder.setNursingId(nursingId); + nursingElder.setElderId(elderId); + list.add(nursingElder); + }); + }); + + //删除所有的对应的关系 + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.in(NursingElder::getElderId, elderIds); + nursingElderMapper.delete(wrapper); + //批量新增 + return saveBatch(list); + } + + /** + * 查询护理员老人关联 + * + * @param id 护理员老人关联主键 + * @return 护理员老人关联 + */ + @Override + public NursingElder selectNursingElderById(Long id) { + return getById(id); + } + + /** + * 查询护理员老人关联列表 + * + * @param nursingElder 护理员老人关联 + * @return 护理员老人关联 + */ + @Override + public List selectNursingElderList(NursingElder nursingElder) { + return nursingElderMapper.selectNursingElderList(nursingElder); + } + + /** + * 新增护理员老人关联 + * + * @param nursingElder 护理员老人关联 + * @return 结果 + */ + @Override + public int insertNursingElder(NursingElder nursingElder) { + return save(nursingElder) ? 1 : 0; + } + + /** + * 修改护理员老人关联 + * + * @param nursingElder 护理员老人关联 + * @return 结果 + */ + @Override + public int updateNursingElder(NursingElder nursingElder) { + return updateById(nursingElder) ? 1 : 0; + } + + /** + * 批量删除护理员老人关联 + * + * @param ids 需要删除的护理员老人关联主键 + * @return 结果 + */ + @Override + public int deleteNursingElderByIds(Long[] ids) { + return removeByIds(Arrays.asList(ids)) ? 1 : 0; + } + + /** + * 删除护理员老人关联信息 + * + * @param id 护理员老人关联主键 + * @return 结果 + */ + @Override + public int deleteNursingElderById(Long id) { + return removeById(id) ? 1 : 0; + } +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/NursingLevelServiceImpl.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/NursingLevelServiceImpl.java new file mode 100644 index 0000000..d4d9256 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/NursingLevelServiceImpl.java @@ -0,0 +1,159 @@ +package com.zzyl.nursing.service.impl; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import cn.hutool.core.bean.BeanUtil; +import com.zzyl.common.constant.CacheConstants; +import com.zzyl.nursing.vo.NursingLevelVo; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Service; +import com.zzyl.nursing.mapper.NursingLevelMapper; +import com.zzyl.nursing.domain.NursingLevel; +import com.zzyl.nursing.service.INursingLevelService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; + +/** + * 护理等级Service业务层处理 + * + * @Author: Zhy + * @Date: 2024-12-30 + */ +@Service +@Slf4j +@RequiredArgsConstructor +public class NursingLevelServiceImpl extends ServiceImpl implements INursingLevelService { + + private final NursingLevelMapper nursingLevelMapper; + private final RedisTemplate redisTemplate; + + /** + * 查询护理等级 + * + * @param id 护理等级主键 + * @return 护理等级 + */ + @Override + public NursingLevel selectNursingLevelById(Long id) { + return nursingLevelMapper.selectById(id); + } + + /** + * 查询护理等级列表 + * + * @param nursingLevel 护理等级 + * @return 护理等级 + */ + @Override + public List selectNursingLevelList(NursingLevel nursingLevel) { + return nursingLevelMapper.selectNursingLevelList(nursingLevel); + } + + /** + * 新增护理等级 + * + * @param nursingLevel 护理等级 + * @return 结果 + */ + @Override + public int insertNursingLevel(NursingLevel nursingLevel) { + nursingLevelMapper.insert(nursingLevel); + // 清除缓存 + redisTemplate.delete(CacheConstants.NURSING_LEVEL_ENABLE_KEY); + return 1; + } + + /** + * 修改护理等级 + * + * @param nursingLevel 护理等级 + * @return 结果 + */ + @Override + public int updateNursingLevel(NursingLevel nursingLevel) { + nursingLevelMapper.updateById(nursingLevel); + // 清除缓存 + redisTemplate.delete(CacheConstants.NURSING_LEVEL_ENABLE_KEY); + return 1; + } + + /** + * 批量删除护理等级 + * + * @param ids 需要删除的护理等级主键 + * @return 结果 + */ + @Override + public int deleteNursingLevelByIds(Long[] ids) { + nursingLevelMapper.deleteBatchIds(Arrays.asList(ids)); + // 清除缓存 + redisTemplate.delete(CacheConstants.NURSING_LEVEL_ENABLE_KEY); + return 1; + } + + /** + * 删除护理等级信息 + * + * @param id 护理等级主键 + * @return 结果 + */ + @Override + public int deleteNursingLevelById(Long id) { + nursingLevelMapper.deleteById(id); + // 清除缓存 + redisTemplate.delete(CacheConstants.NURSING_LEVEL_ENABLE_KEY); + return 1; + } + + /** + * 查询护理等级Vo列表 + * + * @param nursingLevel 条件 + * @return 结果 + */ + @Override + public List selectNursingLevelVoList(NursingLevel nursingLevel) { + return nursingLevelMapper.selectNursingLevelVoList(nursingLevel); + } + + /** + * 查询所有已启用的护理等级 + * + * @return: + * @param: + */ + @Override + public List selectByEnable() { + // 从 Redis 中获取已启用的护理等级 + List list; + + try { + list = (List) redisTemplate.opsForValue().get(CacheConstants.NURSING_LEVEL_ENABLE_KEY); + } catch (Exception e) { + throw new RuntimeException(e); + } + if (BeanUtil.isNotEmpty(list)) { + log.info("从 Redis 中获取已启用的护理等级"); + return list; + } + + log.info("从数据库中查询护理等级"); + + list = this.lambdaQuery().eq(NursingLevel::getStatus, 1).list(); + + // 将从数据库中查询到的护理等级存入 Redis 中 + if (BeanUtil.isNotEmpty(list)) { + // 使用 try-catch 防止 Redis 失败导致主程序崩溃 + try { + redisTemplate.opsForValue().set(CacheConstants.NURSING_LEVEL_ENABLE_KEY, list, 60 * 60 * 24, TimeUnit.SECONDS); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + return list; + } +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/NursingPlanServiceImpl.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/NursingPlanServiceImpl.java new file mode 100644 index 0000000..5111a92 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/NursingPlanServiceImpl.java @@ -0,0 +1,215 @@ +package com.zzyl.nursing.service.impl; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import cn.hutool.core.util.ObjectUtil; +import com.zzyl.common.constant.CacheConstants; +import com.zzyl.common.utils.bean.BeanUtils; +import com.zzyl.nursing.domain.NursingProjectPlan; +import com.zzyl.nursing.dto.NursingPlanDto; +import com.zzyl.nursing.mapper.NursingProjectPlanMapper; +import com.zzyl.nursing.vo.NursingPlanVo; +import com.zzyl.nursing.vo.NursingProjectPlanVo; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Service; +import com.zzyl.nursing.mapper.NursingPlanMapper; +import com.zzyl.nursing.domain.NursingPlan; +import com.zzyl.nursing.service.INursingPlanService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.transaction.annotation.Transactional; + +/** + * 护理计划Service业务层处理 + * + * @Author: Zhy + * @Date: 2024-12-30 + */ +@Service +@Slf4j +@RequiredArgsConstructor +public class NursingPlanServiceImpl extends ServiceImpl implements INursingPlanService { + + private final NursingPlanMapper nursingPlanMapper; + private final NursingProjectPlanMapper nursingProjectPlanMapper; + private final RedisTemplate redisTemplate; + + /** + * 查询护理计划 + * + * @param id 护理计划主键 + * @return 护理计划 + */ + @Override + public NursingPlanVo selectNursingPlanById(Long id) { + // 1.获取护理计划基本信息 + NursingPlan nursingPlan = getById(id); + + // 2.获取当前护理计划关联的护理项目列表 + List projectList = nursingProjectPlanMapper.getProjectListByPlanId(id); + + // 3.构建一个NursingPlanVo对象并返回 + NursingPlanVo nursingPlanVo = new NursingPlanVo(); + BeanUtils.copyProperties(nursingPlan, nursingPlanVo); + nursingPlanVo.setProjectPlans(projectList); + + return nursingPlanVo; + } + + /** + * 查询护理计划列表 + * + * @param nursingPlan 护理计划 + * @return 护理计划 + */ + @Override + public List selectNursingPlanList(NursingPlan nursingPlan) { + return nursingPlanMapper.selectNursingPlanList(nursingPlan); + } + + /** + * 新增护理计划 + * + * @param nursingPlanDto 护理计划 + * @return 结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int insertNursingPlan(NursingPlanDto nursingPlanDto) { + // 1.保存护理计划基本信息 + NursingPlan nursingPlan = new NursingPlan(); + BeanUtils.copyProperties(nursingPlanDto, nursingPlan); + save(nursingPlan); + + // 2.批量保存护理计划关联的护理项目 + List projectPlans = nursingPlanDto.getProjectPlans(); + int rows = nursingProjectPlanMapper.insertBatch(projectPlans, nursingPlan.getId()); + + // 删除 Redis 缓存中所有护理计划 + try { + redisTemplate.delete(CacheConstants.NURSING_PLAN_ENABLE_KEY); + } catch (Exception e) { + throw new RuntimeException(e); + } + + // 3.返回结果 + return rows > 0 ? 1 : 0; + } + + /** + * 修改护理计划 + * + * @param nursingPlanDto 护理计划 + * @return 结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int updateNursingPlan(NursingPlanDto nursingPlanDto) { + // 1.修改护理计划关联的护理项目列表 + List projectPlans = nursingPlanDto.getProjectPlans(); + // 判断护理计划关联的护理项目是否为空 + if (projectPlans != null && !projectPlans.isEmpty()) { + // 1.1 删除当前护理计划关联的所有护理项目 + nursingProjectPlanMapper.deleteByPlanId(nursingPlanDto.getId()); + + // 2.2 批量保存护理计划新关联的护理项目 + nursingProjectPlanMapper.insertBatch(projectPlans, nursingPlanDto.getId()); + } + + // 2.修改护理计划的基本信息 + NursingPlan nursingPlan = new NursingPlan(); + BeanUtils.copyProperties(nursingPlanDto, nursingPlan); + + // 删除 Redis 缓存中所有护理计划 + try { + redisTemplate.delete(CacheConstants.NURSING_PLAN_ENABLE_KEY); + } catch (Exception e) { + throw new RuntimeException(e); + } + + return updateById(nursingPlan) ? 1 : 0; + } + + /** + * 批量删除护理计划 + * + * @param ids 需要删除的护理计划主键 + * @return 结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int deleteNursingPlanByIds(Long[] ids) { + // 1.批量删除护理计划关联的护理项目 + nursingProjectPlanMapper.batchDeleteByPlanIds(Arrays.asList(ids)); + + // 2.删除护理计划基本信息 + nursingPlanMapper.deleteBatchIds(Arrays.asList(ids)); + + // 删除 Redis 缓存中所有护理计划 + try { + redisTemplate.delete(CacheConstants.NURSING_PLAN_ENABLE_KEY); + } catch (Exception e) { + throw new RuntimeException(e); + } + + return 1; + } + + /** + * 删除护理计划信息 + * + * @param id 护理计划主键 + * @return 结果 + */ + @Override + public int deleteNursingPlanById(Long id) { + nursingPlanMapper.deleteById(id); + + // 删除 Redis 缓存中所有护理计划 + try { + redisTemplate.delete(CacheConstants.NURSING_PLAN_ENABLE_KEY); + } catch (Exception e) { + throw new RuntimeException(e); + } + + return 1; + } + + /** + * 查询所有护理计划 + * + * @return 护理计划列表 + */ + @Override + public List getAllNursingPlans() { + // 从 Redis 缓存中获取所有启用状态的护理计划 + List list; + + try { + list = (List) redisTemplate.opsForValue().get(CacheConstants.NURSING_PLAN_ENABLE_KEY); + } catch (Exception e) { + throw new RuntimeException(e); + } + if (ObjectUtil.isNotNull(list)) { + log.info("从 Redis 缓存中获取所有启用状态的护理计划"); + return list; + } + + log.info("从数据库中获取所有启用状态的护理计划"); + list = this.lambdaQuery().eq(NursingPlan::getStatus, 1).list(); + + // 将查询到的护理计划存储到 Redis 缓存中 + if (ObjectUtil.isNotNull(list)) { + try { + redisTemplate.opsForValue().set(CacheConstants.NURSING_PLAN_ENABLE_KEY, list, 60 * 60 * 24, TimeUnit.SECONDS); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + return list; + } +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/NursingProjectServiceImpl.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/NursingProjectServiceImpl.java new file mode 100644 index 0000000..803be9f --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/NursingProjectServiceImpl.java @@ -0,0 +1,167 @@ +package com.zzyl.nursing.service.impl; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import cn.hutool.core.util.ObjectUtil; +import com.zzyl.common.constant.CacheConstants; +import com.zzyl.common.utils.DateUtils; +import com.zzyl.nursing.vo.NursingProjectVo; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Service; +import com.zzyl.nursing.mapper.NursingProjectMapper; +import com.zzyl.nursing.domain.NursingProject; +import com.zzyl.nursing.service.INursingProjectService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; + +/** + * 护理项目Service业务层处理 + * + * @Author: Zhy + * @Date: 2024-12-30 + */ +@Service +@Slf4j +@RequiredArgsConstructor +public class NursingProjectServiceImpl extends ServiceImpl implements INursingProjectService { + + private final NursingProjectMapper nursingProjectMapper; + private final RedisTemplate redisTemplate; + + /** + * 查询护理项目 + * + * @param id 护理项目主键 + * @return 护理项目 + */ + @Override + public NursingProject selectNursingProjectById(Long id) { + return nursingProjectMapper.selectById(id); + } + + /** + * 查询护理项目列表 + * + * @param nursingProject 护理项目 + * @return 护理项目 + */ + @Override + public List selectNursingProjectList(NursingProject nursingProject) { + return nursingProjectMapper.selectNursingProjectList(nursingProject); + } + + /** + * 新增护理项目 + * + * @param nursingProject 护理项目 + * @return 结果 + */ + @Override + public int insertNursingProject(NursingProject nursingProject) { + return nursingProjectMapper.insert(nursingProject); + } + + /** + * 修改护理项目 + * + * @param nursingProject 护理项目 + * @return 结果 + */ + @Override + public int updateNursingProject(NursingProject nursingProject) { + nursingProjectMapper.updateById(nursingProject); + + // 清除缓存 + try { + redisTemplate.delete(CacheConstants.NURSING_PROJECT_ENABLE_KEY); + } catch (Exception e) { + throw new RuntimeException(e); + } + + return 1; + } + + /** + * 批量删除护理项目 + * + * @param ids 需要删除的护理项目主键 + * @return 结果 + */ + @Override + public int deleteNursingProjectByIds(Long[] ids) { + nursingProjectMapper.deleteBatchIds(Arrays.asList(ids)); + + // 清除缓存 + try { + redisTemplate.delete(CacheConstants.NURSING_PROJECT_ENABLE_KEY); + } catch (Exception e) { + throw new RuntimeException(e); + } + + return 1; + } + + /** + * 删除护理项目信息 + * + * @param id 护理项目主键 + * @return 结果 + */ + @Override + public int deleteNursingProjectById(Long id) { + nursingProjectMapper.deleteById(id); + + // 清除缓存 + try { + redisTemplate.delete(CacheConstants.NURSING_PROJECT_ENABLE_KEY); + } catch (Exception e) { + throw new RuntimeException(e); + } + + return 1; + } + + /** + * 查询所有护理项目VO列表 + * + * @return 结果 + */ + @Override + public List getAllProjects() { + // 从缓存中获取数据 + List list; + + + try { + list = (List) redisTemplate.opsForValue().get(CacheConstants.NURSING_PROJECT_ENABLE_KEY); + } catch (Exception e) { + throw new RuntimeException(e); + } + if (ObjectUtil.isNotEmpty(list)) { + log.info("从 Redis 缓存中获取护理项目数据"); + return list; + } + + log.info("从数据库中获取以启用的护理项目数据"); + list = nursingProjectMapper.getAllProjects(); + + // 缓存数据 + if (ObjectUtil.isNotEmpty(list)) { + try { + redisTemplate.opsForValue().set(CacheConstants.NURSING_PROJECT_ENABLE_KEY, + list, + 60 * 60 * 24, + TimeUnit.SECONDS + ); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + return list; + } +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/NursingTaskServiceImpl.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/NursingTaskServiceImpl.java new file mode 100644 index 0000000..8296996 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/NursingTaskServiceImpl.java @@ -0,0 +1,519 @@ +package com.zzyl.nursing.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.IdcardUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.zzyl.common.core.domain.R; +import com.zzyl.common.core.domain.entity.SysUser; +import com.zzyl.common.core.page.TableDataInfo; +import com.zzyl.common.exception.base.BaseException; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.nursing.domain.*; +import com.zzyl.nursing.dto.NursingTaskCancelDto; +import com.zzyl.nursing.dto.NursingTaskDoDto; +import com.zzyl.nursing.dto.NursingTaskDto; +import com.zzyl.nursing.dto.NursingTaskUpdateDto; +import com.zzyl.nursing.mapper.ElderMapper; +import com.zzyl.nursing.mapper.NursingTaskMapper; +import com.zzyl.nursing.service.*; +import com.zzyl.nursing.vo.NursingPlanVo; +import com.zzyl.nursing.vo.NursingProjectPlanVo; +import com.zzyl.nursing.vo.NursingTaskVo; +import com.zzyl.system.service.ISysUserService; +import io.netty.handler.codec.http.HttpConstants; +import io.netty.handler.codec.http.HttpResponse; +import io.netty.handler.codec.http.HttpResponseStatus; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.Month; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * 护理任务Service业务层处理 + * + * @author ruoyi + * @date 2024-09-27 + */ +@Service +@Slf4j +public class NursingTaskServiceImpl extends ServiceImpl implements INursingTaskService +{ + @Autowired + private NursingTaskMapper nursingTaskMapper; + + /** + * 查询护理任务 + * + * @param id 护理任务主键 + * @return 护理任务 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public NursingTaskVo selectNursingTaskById(Long id) + { + NursingTask nursingTask = this.lambdaQuery().eq(NursingTask::getId, id).one(); + if (ObjectUtil.isEmpty(nursingTask)) { + throw new BaseException("查询任务不存在"); + } + NursingTaskVo nursingTaskVo = BeanUtil.toBean(nursingTask, NursingTaskVo.class); + if (StrUtil.isNotEmpty(nursingTask.getUpdateBy())) { + SysUser sysUser = sysUserService.selectUserById(Long.valueOf(nursingTask.getUpdateBy())); + nursingTaskVo.setUpdater(sysUser.getNickName()); + } + CheckIn checkIn = checkInService.getOne(Wrappers.lambdaQuery().eq(CheckIn::getElderId, nursingTask.getElderId())); + nursingTaskVo.setAge(IdcardUtil.getAgeByIdCard(checkIn.getIdCardNo())); + nursingTaskVo.setNursingLevelName(checkIn.getNursingLevelName()); + String nursingId = nursingTask.getNursingId(); + List list = Arrays.asList(nursingId.split(",")); + List nursingName = new ArrayList<>(); + list.forEach(nurser -> { + SysUser User = sysUserService.selectUserById(Long.valueOf(nurser)); + nursingName.add(User.getNickName()); + }); + nursingTaskVo.setNursingName(nursingName); + return nursingTaskVo; + } + + /** + * 查询护理任务列表 + * + * @param nursingTask 护理任务 + * @return 护理任务 + */ + @Override + public List selectNursingTaskList(NursingTask nursingTask) + { + return nursingTaskMapper.selectNursingTaskList(nursingTask); + } + + /** + * 新增护理任务 + * + * @param nursingTask 护理任务 + * @return 结果 + */ + @Override + public int insertNursingTask(NursingTask nursingTask) + { + return save(nursingTask)?1:0; + } + + /** + * 修改护理任务 + * + * @param nursingTask 护理任务 + * @return 结果 + */ + @Override + public int updateNursingTask(NursingTask nursingTask) + { + return updateById(nursingTask)?1:0; + } + + /** + * 批量删除护理任务 + * + * @param ids 需要删除的护理任务主键 + * @return 结果 + */ + @Override + public int deleteNursingTaskByIds(Long[] ids) + { + return removeByIds(Arrays.asList(ids))?1:0; + } + + /** + * 删除护理任务信息 + * + * @param id 护理任务主键 + * @return 结果 + */ + @Override + public int deleteNursingTaskById(Long id) + { + return removeById(id)?1:0; + } + + @Autowired + private ICheckInService checkInService; + + @Autowired + private ICheckInConfigService checkInConfigService; + + @Autowired + private INursingLevelService nursingLevelService; + + @Autowired + private INursingPlanService nursingPlanService; + + @Autowired + private INursingElderService nursingElderService; + + @Autowired + private INursingProjectService nursingProjectService; + + @Autowired + private ISysUserService sysUserService; + + /** + * 生成护理任务 + * + * @param elder + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void createMonthTask(Elder elder) { + //校验 + if (elder == null || elder.getId() == null) { + log.info("老人不能为空"); + return; + } + + //获取入住信息 + CheckIn checkIn = checkInService.getOne(Wrappers.lambdaQuery().eq(CheckIn::getElderId, elder.getId())); + + //获取入住及入住配置信息 + CheckInConfig checkInConfig = checkInConfigService.getOne(Wrappers.lambdaQuery().eq(CheckInConfig::getCheckInId, checkIn.getId())); + if (ObjectUtil.isEmpty(checkInConfig)) { + return; + } + //开始时间 + LocalDateTime startTime = LocalDateTime.now(); + //判断开始是在当天时间 + if (checkInConfig.getFeeStartDate().toLocalDate().isEqual(LocalDateTime.now().toLocalDate())) { + startTime = checkInConfig.getFeeStartDate(); + } + + //护理等级 + NursingLevel nursingLevel = nursingLevelService.selectNursingLevelById(checkInConfig.getNursingLevelId()); + //护理计划 + NursingPlanVo nursingPlanVo = nursingPlanService.selectNursingPlanById(nursingLevel.getLplanId()); + //查询老人对应的护理员列表 + List nursingElderList = nursingElderService.list(Wrappers.lambdaQuery().eq(NursingElder::getElderId, elder.getId())); + String nursingIds; + if (CollUtil.isNotEmpty(nursingElderList)) { + List list = nursingElderList.stream().map(NursingElder::getNursingId).collect(Collectors.toList()); + //多个id用逗号分隔,转换为字符串 + nursingIds = StringUtils.join(list, ","); + } else { + nursingIds = ""; + } + + //查询所有的护理项目 + List list = nursingProjectService.list(); + //转换为map key是id,value是name + Map nursingProjectMap = list.stream().collect(Collectors.toMap(NursingProject::getId, NursingProject::getName)); + + //组装护理任务 + List nursingTasks = new ArrayList<>(); + + LocalDateTime finalStartTime = startTime; + nursingPlanVo.getProjectPlans().forEach(v -> { + //执行频次 + Integer executeFrequency = Math.toIntExact(v.getExecuteFrequency()); + //执行时间 + String executeTime = v.getExecuteTime(); + LocalTime localTime = LocalTime.parse(executeTime); + //开始执行时间 + LocalDateTime firstExecutionTime = LocalDateTime.of(finalStartTime.toLocalDate(), localTime); + // 计算相差天数 + + int year = finalStartTime.getYear(); + Month month = checkInConfig.getFeeStartDate().getMonth(); + int i = finalStartTime.toLocalDate().lengthOfMonth(); + + LocalDateTime monthEndTime = LocalDateTime.of(finalStartTime.getYear(), checkInConfig.getFeeStartDate().getMonth(), finalStartTime.toLocalDate().lengthOfMonth(), 23, 59); + // 间隔天数 + long diffDays = monthEndTime.toLocalDate().toEpochDay() - finalStartTime.toLocalDate().toEpochDay() + 1; + if (v.getExecuteCycle().equals(0)) { + // 日 + createTaskByDay(firstExecutionTime, diffDays, nursingTasks, executeFrequency, elder, v, nursingIds,nursingProjectMap); + } else if (v.getExecuteCycle().equals(1)) { + // 周 + createTaskByWeek(firstExecutionTime, diffDays, nursingTasks, executeFrequency, elder, v, monthEndTime, nursingIds,nursingProjectMap); + } else { + // 月 + createTaskByMonth(firstExecutionTime, monthEndTime, nursingTasks, executeFrequency, elder, v, nursingIds,nursingProjectMap); + } + }); + + if (CollUtil.isEmpty(nursingTasks)) { + return; + } + nursingTasks.forEach(v -> { + v.setTaskType("1"); + }); + saveBatch(nursingTasks); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public TableDataInfo list(NursingTaskDto nursingTaskDto) { + Page page = new Page<>(nursingTaskDto.getPageNum(), nursingTaskDto.getPageSize()); + LocalDateTime start = nursingTaskDto.getStartTime(); + LocalDateTime end = nursingTaskDto.getEndTime(); + page(page, Wrappers.lambdaQuery() + .like(StrUtil.isNotEmpty(nursingTaskDto.getElderName()), NursingTask::getElderName, nursingTaskDto.getElderName()) + .eq(ObjectUtil.isNotEmpty(nursingTaskDto.getNurseId()), NursingTask::getNursingId, nursingTaskDto.getNurseId()) + .eq(ObjectUtil.isNotEmpty(nursingTaskDto.getProjectId()), NursingTask::getProjectId, nursingTaskDto.getProjectId()) + .between(ObjectUtil.isNotEmpty(start) && ObjectUtil.isNotEmpty(end), NursingTask::getEstimatedServerTime, start, end)); + List records = page.getRecords(); + List collect = records.stream().map(v -> { + NursingTaskVo nursingTaskVo = BeanUtil.toBean(v, NursingTaskVo.class); + NursingProject nursingProject = nursingProjectService.getOne(Wrappers.lambdaQuery().eq(NursingProject::getId, v.getProjectId())); + nursingTaskVo.setProjectName(nursingProject.getName()); + String nursingId = nursingTaskVo.getNursingId(); + List list = Arrays.asList(nursingId.split(",")); + List nursingName = new ArrayList<>(); + list.forEach(nurser -> { + SysUser User = sysUserService.selectUserById(Long.valueOf(nurser)); + nursingName.add(User.getNickName()); + }); + nursingTaskVo.setNursingName(nursingName); + v.setProjectName(nursingProject.getName()); + updateById(v); + return nursingTaskVo; + }).collect(Collectors.toList()); + + TableDataInfo dataInfo = new TableDataInfo<>(); + dataInfo.setCode(200); + dataInfo.setMsg("查询成功"); + dataInfo.setRows(collect); + dataInfo.setTotal(page.getTotal()); + return dataInfo; + } + + /** + * 取消任务 + * @param nursingTaskCancelDto 取消任务原因dto + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void cancel(NursingTaskCancelDto nursingTaskCancelDto) { + NursingTask nursingTask = this.lambdaQuery().eq(NursingTask::getId, nursingTaskCancelDto.getTaskId()).one(); + if (ObjectUtil.isEmpty(nursingTask)) { + throw new BaseException("取消任务不存在"); + } + nursingTask.setCancelReason(nursingTaskCancelDto.getReason()); + nursingTask.setStatus(3); + updateById(nursingTask); + } + + /** + * 执行任务 + * @param nursingTaskDoDto 执行任务dto + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void doTask(NursingTaskDoDto nursingTaskDoDto) { + NursingTask nursingTask = this.lambdaQuery().eq(NursingTask::getId, nursingTaskDoDto.getTaskId()).one(); + if (ObjectUtil.isEmpty(nursingTask)) { + throw new BaseException("执行任务不存在"); + } + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + nursingTask.setRealServerTime(LocalDateTime.parse(nursingTaskDoDto.getEstimatedServerTime(), formatter)); + nursingTask.setMark(nursingTaskDoDto.getMark()); + nursingTask.setTaskImage(nursingTaskDoDto.getTaskImage()); + nursingTask.setStatus(2); + updateById(nursingTask); + } + + /** + * 更新时间 + * @param nursingTaskUpdateDto + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void updateTime(NursingTaskUpdateDto nursingTaskUpdateDto) { + NursingTask nursingTask = this.lambdaQuery().eq(NursingTask::getId, nursingTaskUpdateDto.getTaskId()).one(); + if (ObjectUtil.isEmpty(nursingTask)) { + throw new BaseException("执行任务不存在"); + } + // 创建一个自定义的 DateTimeFormatter + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + nursingTask.setEstimatedServerTime(LocalDateTime.parse(nursingTaskUpdateDto.getEstimatedServerTime(), formatter)); + updateById(nursingTask); + } + + /** + * 按月创建任务 + * + * @param firstExecutionTime + * @param monthEndTime + * @param nursingTasks + * @param executeFrequency + * @param elder + * @param v + */ + private void createTaskByMonth(LocalDateTime firstExecutionTime, LocalDateTime monthEndTime, List nursingTasks, Integer executeFrequency, Elder elder, NursingProjectPlanVo v, String nursingIds, Map nursingProjectMap) { + LocalDateTime executionTime = firstExecutionTime; + Integer diffDay = (monthEndTime.plusSeconds(1).getDayOfMonth() - executionTime.getDayOfMonth()) / executeFrequency; + for (int x = 0; x < executeFrequency; x++) { + // 根据时间差和执行顺序计算每个任务的具体时间 + LocalDateTime seconds = executionTime.plusDays(diffDay * x); + // 初始化护理任务对象 + NursingTask nursingTask = getNursingTask(elder, v, nursingIds, seconds,nursingProjectMap); + // 将生成的任务添加到任务列表中 + nursingTasks.add(nursingTask); + } + } + + /** + * 根据周为单位创建护理任务 + * + * 此方法旨在根据给定的开始时间、差异天数、执行频率等参数,为指定的老人生成护理任务列表 + * 它考虑了跨年情况以及每月结束时间的限制,避免生成越过月末的有效任务 + * + * @param firstExecutionTime 首次执行时间,用于计算后续任务的时间点 + * @param diffDays 任务之间的时间差,以天为单位,此方法专注于周级别,故此值应与7的倍数有关 + * @param nursingTasks 护理任务列表,方法将新生成的任务添加到此列表中 + * @param executeFrequency 执行频率,决定每周内任务执行的次数 + * @param elder 老人信息对象,任务相关的老人信息由此对象提供 + * @param v 护理项目计划的视图对象,包含项目ID等信息 + * @param monthEndTime 每月结束时间的限制,确保任务不会跨月生成 + * @param nursingIds 护理员ID列表,以字符串形式传递,用于分配任务给护理员 + */ + private void createTaskByWeek(LocalDateTime firstExecutionTime, long diffDays, List nursingTasks, Integer executeFrequency, Elder elder, NursingProjectPlanVo v, LocalDateTime monthEndTime, String nursingIds,Map nursingProjectMap) { + int i; + // 以7天为步长遍历差异天数,创建每周的任务 + for (i = 0; i < diffDays - 7; i = i + 7) { + // 计算每周结束时间 + LocalDateTime dayEndTime = LocalDateTime.of(firstExecutionTime.plusDays(i + 7).toLocalDate(), LocalTime.of(23, 59)); + // 计算本周的执行起始时间 + LocalDateTime executionTime = firstExecutionTime.plusDays(i); + // 根据执行频率计算时间差,用于确定本周内各任务的时间点 + Integer diffDay = (dayEndTime.plusSeconds(1).getDayOfYear() - executionTime.getDayOfYear()) / executeFrequency; + // 根据执行频率生成本周的任务 + for (int x = 0; x < executeFrequency; x++) { + // 根据时间差和执行顺序计算每个任务的具体时间 + LocalDateTime seconds = executionTime.plusDays(diffDay * x); + // 初始化护理任务对象 + NursingTask nursingTask = getNursingTask(elder, v, nursingIds, seconds,nursingProjectMap); + // 将生成的任务添加到任务列表中 + nursingTasks.add(nursingTask); + } + } + + // 处理边界情况,当i超过diffDays-7且小于diffDays时 + if (i > diffDays - 7 && i < diffDays) { + // 计算到达diffDays时的结束时间 + LocalDateTime dayEndTime = LocalDateTime.of(firstExecutionTime.plusDays(i + 7).toLocalDate(), LocalTime.of(23, 59)); + // 如果结束时间与开始时间年份不同,则返回,避免跨年任务 + if (ObjectUtil.notEqual(dayEndTime.getYear(), firstExecutionTime.getYear())) { + return; + } + // 计算执行时间 + LocalDateTime executionTime = firstExecutionTime.plusDays(i); + // 计算时间差,确定任务时间点 + Integer diffDay = (dayEndTime.plusSeconds(1).getDayOfYear() - executionTime.getDayOfYear()) / executeFrequency; + // 根据执行频率生成任务,直到月末 + for (int x = 0; x < executeFrequency; x++) { + // 计算每个任务的时间 + LocalDateTime seconds = executionTime.plusDays(diffDay * x); + // 如果任务时间超过月末结束时间,则停止生成 + if (seconds.isAfter(monthEndTime)) { + break; + } + // 初始化护理任务对象 + NursingTask nursingTask = getNursingTask(elder, v, nursingIds, seconds,nursingProjectMap); + // 将生成的任务添加到任务列表中 + nursingTasks.add(nursingTask); + } + } + + } + + + + + /** + * 按日创建任务 + * @param firstExecutionTime + * @param diffDays + * @param nursingTasks + * @param executeFrequency + * @param elder + * @param v + */ + /** + * 根据天数创建护理任务 + *

+ * 该方法根据首次执行时间、任务间隔天数、护理任务列表、执行频率、老人信息和护理项目计划数据, + * 创建一系列的护理任务。任务的创建以天为单位,直到达到任务间隔天数为止。 + * + * @param firstExecutionTime 首次执行时间,标志着任务创建的起始时间 + * @param diffDays 任务间隔天数,确定需要创建任务的天数范围 + * @param nursingTasks 护理任务列表,创建的任务将被添加到此列表中 + * @param executeFrequency 执行频率,决定一天内任务执行的次数 + * @param elder 老人对象,包含执行任务的老人的信息 + * @param v 护理项目计划数据对象,包含护理项目的相关信息 + */ + private void createTaskByDay(LocalDateTime firstExecutionTime, long diffDays, List nursingTasks, Integer executeFrequency, Elder elder, NursingProjectPlanVo v, String nursingIds,Map nursingProjectMap) { + // 遍历每一天,从首次执行时间开始,直到达到任务间隔天数 + for (int i = 0; i < diffDays; i++) { + // 计算每一天的任务执行起始时间 + LocalDateTime executionTime = firstExecutionTime.plusDays(i); + // 确定当天任务执行的结束时间(当天的23:59) + LocalDateTime dayEndTime = LocalDateTime.of(executionTime.toLocalDate(), LocalTime.of(23, 59)); + // 计算当天内每次执行任务之间的小时差,用于确定执行时间点 + Integer diffHour = (dayEndTime.plusSeconds(1).getHour() - executionTime.getHour()) / executeFrequency; + // 根据执行频率创建任务 + for (int x = 0; x < executeFrequency; x++) { + // 计算每个任务的具体执行时间 + LocalDateTime seconds = executionTime.plusHours(diffHour * x); + // 创建新的护理任务对象 + NursingTask nursingTask = getNursingTask(elder, v, nursingIds, seconds,nursingProjectMap); + // 将生成的任务添加到任务列表中 + nursingTasks.add(nursingTask); + } + } + } + + /** + * 获取护理任务对象 + * @param elder + * @param v + * @param nursingIds + * @param seconds + * @return + */ + private NursingTask getNursingTask(Elder elder, NursingProjectPlanVo v, String nursingIds, LocalDateTime seconds,Map nursingProjectMap) { + NursingTask nursingTask = new NursingTask(); + // 设置任务状态 + nursingTask.setStatus(1); + // 设置护理员ID列表 + nursingTask.setNursingId(nursingIds); + // 老人姓名 + nursingTask.setElderName(elder.getName()); + // 设置床位号 + nursingTask.setBedNumber(elder.getBedNumber()); + // 设置预估服务时间 + nursingTask.setEstimatedServerTime(seconds); + // 设置项目ID + nursingTask.setProjectId(Integer.valueOf(v.getProjectId())); + // 设置老人ID + nursingTask.setElderId(elder.getId()); + //匹配护理项目 + nursingTask.setProjectName(nursingProjectMap.get(nursingTask.getProjectId())); + + return nursingTask; + } + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/RoomServiceImpl.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/RoomServiceImpl.java new file mode 100644 index 0000000..b1770a3 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/RoomServiceImpl.java @@ -0,0 +1,160 @@ +package com.zzyl.nursing.service.impl; + +import cn.hutool.core.util.ObjUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.zzyl.common.constant.CacheConstants; +import com.zzyl.nursing.domain.DeviceData; +import com.zzyl.nursing.domain.Room; +import com.zzyl.nursing.mapper.RoomMapper; +import com.zzyl.nursing.service.IRoomService; +import com.zzyl.nursing.vo.BedVo; +import com.zzyl.nursing.vo.RoomVo; +import lombok.RequiredArgsConstructor; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.List; + +/** + * 房间Service业务层处理 + * + * @author ruoyi + * @date 2024-04-26 + */ +@Service +@RequiredArgsConstructor +public class RoomServiceImpl extends ServiceImpl implements IRoomService { + + private final RoomMapper roomMapper; + private final RedisTemplate redisTemplate; + + /** + * 查询房间 + * + * @param id 房间主键 + * @return 房间 + */ + @Override + public Room selectRoomById(Long id) { + return getById(id); + } + + /** + * 查询房间列表 + * + * @param room 房间 + * @return 房间 + */ + @Override + public List selectRoomList(Room room) { + return roomMapper.selectRoomList(room); + } + + /** + * 新增房间 + * + * @param room 房间 + * @return 结果 + */ + @Override + public int insertRoom(Room room) { + return save(room) ? 1 : 0; + } + + /** + * 修改房间 + * + * @param room 房间 + * @return 结果 + */ + @Override + public int updateRoom(Room room) { + return updateById(room) ? 1 : 0; + } + + /** + * 批量删除房间 + * + * @param ids 需要删除的房间主键 + * @return 结果 + */ + @Override + public int deleteRoomByIds(Long[] ids) { + return removeByIds(Arrays.asList(ids)) ? 1 : 0; + } + + /** + * 根据楼层 id 获取房间视图对象列表 + * + * @param: floorId + * @return: + */ + @Override + public List getRoomsByFloorId(Long floorId) { + return roomMapper.selectByFloorId(floorId); + } + + + /** + * 获取所有房间(负责老人) + * + * @param floorId 楼层id + * @return 房间视图对象列表 + */ + @Override + public List getRoomsWithNurByFloorId(Long floorId) { + return roomMapper.selectByFloorIdWithNur(floorId); + } + + /** + * 根据房间id查询 房间 数据 + * + * @return: + * @param: + */ + @Override + public RoomVo getRoomPriceByRoomId(Long id) { + return roomMapper.selectRoomPriceByRoomId(id); + } + + /** + * 获取房间中的智能设备及数据 + * + * @return: + * @param: + */ + @Override + public List getRoomsWithDeviceByFloorId(Long floorId) { + List roomVos = roomMapper.getRoomsWithDeviceByFloorId(floorId); + if (ObjUtil.isNotEmpty(roomVos)) { + roomVos.forEach(roomVo -> { + List bedVoList = roomVo.getBedVoList(); + bedVoList.forEach(bedVo -> { + // 处理床位中的设备数据 + bedVo.getDeviceVos().forEach(deviceVo -> { + String iotId = deviceVo.getIotId(); + // 从 Redis 中获取设备最新数据 + String jsonStr = (String) redisTemplate.opsForHash().get(CacheConstants.IOT_DEVICE_LAST_DATA, iotId); + if (ObjUtil.isNotEmpty(jsonStr)) { + deviceVo.setDeviceDataVos(JSONUtil.toList(jsonStr, DeviceData.class)); + } + }); + }); + + // 处理房间中的设备数据 + roomVo.getDeviceVos().forEach(deviceVo -> { + String iotId = deviceVo.getIotId(); + // 从 Redis 中获取设备最新数据 + String jsonStr = (String) redisTemplate.opsForHash().get(CacheConstants.IOT_DEVICE_LAST_DATA, iotId); + if (ObjUtil.isNotEmpty(jsonStr)) { + deviceVo.setDeviceDataVos(JSONUtil.toList(jsonStr, DeviceData.class)); + } + }); + }); + } + + return roomVos; + } +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/RoomTypeServiceImpl.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/RoomTypeServiceImpl.java new file mode 100644 index 0000000..9ba8f64 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/RoomTypeServiceImpl.java @@ -0,0 +1,115 @@ +package com.zzyl.nursing.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.zzyl.common.exception.base.BaseException; +import com.zzyl.nursing.domain.RoomType; +import com.zzyl.nursing.mapper.RoomTypeMapper; +import com.zzyl.nursing.service.IRoomTypeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.List; + +/** + * 房型Service业务层处理 + * + * @author ruoyi + * @date 2024-04-26 + */ +@Service +public class RoomTypeServiceImpl extends ServiceImpl implements IRoomTypeService +{ + @Autowired + private RoomTypeMapper roomTypeMapper; + + /** + * 查询房型 + * + * @param id 房型主键 + * @return 房型 + */ + @Override + public RoomType selectRoomTypeById(Long id) + { + return getById(id); + } + + /** + * 查询房型列表 + * + * @param roomType 房型 + * @return 房型 + */ + @Override + public List selectRoomTypeList(RoomType roomType) + { + return roomTypeMapper.selectRoomTypeList(roomType); + } + + /** + * 新增房型 + * + * @param roomType 房型 + * @return 结果 + */ + @Override + public int insertRoomType(RoomType roomType) + { + return save(roomType) ? 1 : 0; + } + + /** + * 修改房型 + * + * @param roomType 房型 + * @return 结果 + */ + @Override + public int updateRoomType(RoomType roomType) + { + return updateById(roomType) ? 1 : 0; + } + + /** + * 批量删除房型 + * + * @param ids 需要删除的房型主键 + * @return 结果 + */ + @Override + public int deleteRoomTypeByIds(Long[] ids) + { + return removeByIds(Arrays.asList(ids)) ? 1 : 0; + } + + /** + * 删除房型信息 + * + * @param id 房型主键 + * @return 结果 + */ + @Override + public int deleteRoomTypeById(Long id) + { + return removeById(id) ? 1 : 0; + } + + /** + * 按照状态查询房间类型 + * @param status + * @return + */ + @Override + public List findRoomTypeListByStatus(Integer status) { + + if(ObjectUtil.isEmpty(status)){ + throw new BaseException("参数为空"); + } + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(RoomType::getStatus,status); + return list(wrapper); + } +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/WeChatServiceImpl.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/WeChatServiceImpl.java new file mode 100644 index 0000000..e77fbe9 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/service/impl/WeChatServiceImpl.java @@ -0,0 +1,116 @@ +package com.zzyl.nursing.service.impl; + +import cn.hutool.core.util.ObjUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.http.HttpUtil; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import com.zzyl.common.exception.base.BaseException; +import com.zzyl.nursing.service.IWeChatService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +/** + * 微信小程序服务实现类 + * + * @author Zhy + * @version 1.0 + * @date 2025-03-03 17:06 + */ +@Service +@Slf4j +public class WeChatServiceImpl implements IWeChatService { + + // 登录 + private static final String REQUEST_URL = "https://api.weixin.qq.com/sns/jscode2session?grant_type=authorization_code"; + + // 获取token + private static final String TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential"; + + // 获取手机号 + private static final String PHONE_REQUEST_URL = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token="; + + + @Value("${wechat.mini-program.appId}") + private String appid; + + @Value("${wechat.mini-program.secret}") + private String secret; + + /** + * 获取微信小程序的openid + * + * @return: + * @param: + */ + @Override + public String getOpenId(String code) { + Map params = new HashMap<>(); + params.put("appid", appid); + params.put("secret", secret); + params.put("js_code", code); + + String content = HttpUtil.get(REQUEST_URL, params); + + if (StrUtil.isNotEmpty(content)) { + // 解析json数据 + JSONObject jsonObject = JSONUtil.parseObj(content); + + if (ObjUtil.isNotEmpty(jsonObject) && ObjUtil.isEmpty(jsonObject.get("errcode"))) { + return Objects.toString(jsonObject.get("openid")); + } + } + throw new BaseException("获取openid失败"); + } + + /** + * 获取微信小程序的手机号码 + * + * @return: + * @param: + */ + @Override + public String getPhoneNumber(String detailCode) { + String accessToken = getAccessToken(); + + Map map = Map.of("code", detailCode); + String result = HttpUtil.post(PHONE_REQUEST_URL + accessToken, JSONUtil.toJsonStr(map)); + + if (StrUtil.isNotEmpty(result)) { + JSONObject jsonObject = JSONUtil.parseObj(result); + if (ObjUtil.isNotEmpty(jsonObject) && ObjUtil.equal(jsonObject.getInt("errcode"), 0)) { + return jsonObject.getJSONObject("phone_info").getStr("phoneNumber"); + } + } + throw new BaseException("获取手机号失败"); + } + + /** + * 获取微信小程序的 access_token + * + * @return: + * @param: + */ + public String getAccessToken() { + Map params = new HashMap<>(); + params.put("appid", appid); + params.put("secret", secret); + + String content = HttpUtil.get(TOKEN_URL, params); + + if (StrUtil.isNotEmpty(content)) { + // 解析json数据 + JSONObject jsonObject = JSONUtil.parseObj(content); + + if (ObjUtil.isNotEmpty(jsonObject) && ObjUtil.isEmpty(jsonObject.get("errcode"))) { + return JSONUtil.parseObj(content).getStr("access_token"); + } + } + throw new BaseException("获取openid失败"); + } +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/task/MyTask.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/task/MyTask.java new file mode 100644 index 0000000..3ee2e03 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/task/MyTask.java @@ -0,0 +1,25 @@ +package com.zzyl.nursing.task; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; + +/** + * 自定义定时任务 + * + * @Author: Zhy + * @Date: 2025-02-27 16:57 + * @Version: 1.0 + */ +@Component +@Slf4j +public class MyTask { + + // @Scheduled(cron = "0/5 * * * * ?") + public void executeTask() { + log.info("{}", LocalDateTime.now()); + } + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/util/CodeGeneratorUtil.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/util/CodeGeneratorUtil.java new file mode 100644 index 0000000..2b3d425 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/util/CodeGeneratorUtil.java @@ -0,0 +1,49 @@ +package com.zzyl.nursing.util; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * 合同编码生成器 + * + * @Author: Zhy + * @Date: 2025-02-25 20:24 + * @Version: 1.0 + */ +public class CodeGeneratorUtil { + + private static final AtomicInteger counter = new AtomicInteger(1); + private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss"); + private static final int MAX_COUNTER = 9999; + + // 私有构造函数避免实例化 + private CodeGeneratorUtil() { + throw new AssertionError("Utility class cannot be instantiated."); + } + + /** + * 生成一个16位的合同编号。 + * + * @return 16位的合同编号字符串。 + */ + public static String generateContractNumber() { + // 获取当前时间并格式化 + String currentTime = LocalDateTime.now().format(formatter); + + // 获取并递增计数器 + int count = counter.getAndIncrement(); + if (count > MAX_COUNTER) { + // 如果计数器超过最大值,则重置为最小值 + count = 1; + counter.set(count); + } + + // 将计数器格式化为4位字符串 + String countStr = String.format("%04d", count); + + // 返回完整的合同编号 + return currentTime + countStr; + } + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/util/IDCardUtils.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/util/IDCardUtils.java new file mode 100644 index 0000000..35a3889 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/util/IDCardUtils.java @@ -0,0 +1,93 @@ +package com.zzyl.nursing.util; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.Period; +import java.time.format.DateTimeFormatter; + +/** + * 身份证工具类 + * + * @Author: Zhy + * @Date: 2025-02-28 16:39 + * @Version: 1.0 + */ +public final class IDCardUtils { + + // 私有构造器,防止实例化 + private IDCardUtils() { + throw new AssertionError("Cannot instantiate static class IDCardUtils"); + } + + /** + * 根据身份证号提取个人年龄。 + * + * @param idCard 身份证号码 + * @return 个人年龄,数值类型 + */ + public static int getAgeByIdCard(String idCard) { + LocalDate birthDate = extractBirthDate(idCard); + if (birthDate != null) { + LocalDate currentDate = LocalDate.now(); + return Period.between(birthDate, currentDate).getYears(); + } + throw new IllegalArgumentException("Invalid ID card number."); + } + + /** + * 根据身份证号提取出生日期。 + * + * @param idCard 身份证号码 + * @return 出生日期,LocalDateTime类型 + */ + public static LocalDateTime getBirthDateByIdCard(String idCard) { + // 身份证号码中的出生日期部分 + String birthDateString = idCard.substring(6, 14); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd"); + LocalDate birthDate = LocalDate.parse(birthDateString, formatter); + return LocalDateTime.of(birthDate, LocalTime.MIDNIGHT); + } + + /** + * 根据身份证号提取性别。 + * + * @return: int 性别,0表示女性,1表示男性 + * @param: idCard 身份证号码 + */ + public static int getGenderFromIdCard(String idCard) { + if (idCard == null || idCard.length() != 18) { + throw new IllegalArgumentException("Invalid ID card number"); + } + + // 性别码,身份证号码第17位 + String genderCode = idCard.substring(16, 17); + int gender = Integer.parseInt(genderCode); + + return gender % 2 == 0 ? 1 : 0; + } + + /** + * 内部辅助方法,从身份证号中提取出生日期的LocalDate对象。 + * + * @param idCard 身份证号码 + * @return 出生日期的LocalDate对象,或null(如果身份证号码无效) + */ + private static LocalDate extractBirthDate(String idCard) { + if (idCard == null || idCard.length() != 18) { + return null; + } + try { + String birthStr = idCard.substring(6, 14); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd"); + return LocalDate.parse(birthStr, formatter); + } catch (Exception e) { + return null; + } + } + + public static void main(String[] args) { + System.out.println(getAgeByIdCard("330103199001011234")); + System.out.println(getBirthDateByIdCard("330103199001011234")); + } +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/AlertNotifyVo.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/AlertNotifyVo.java new file mode 100644 index 0000000..89ef9da --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/AlertNotifyVo.java @@ -0,0 +1,58 @@ +package com.zzyl.nursing.vo; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 警告通知vo + * + * @author Zhy + * @version 1.0 + * @date 2025-03-12 12:01 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class AlertNotifyVo { + /** 报警数据id */ + private Long id; + + /** 接入位置 */ + private String accessLocation; + + /** 位置类型 0:随身设备 1:固定设备 */ + private Integer locationType; + + /** 物理位置类型 0楼层 1房间 2床位 */ + private Integer physicalLocationType; + + /** 设备位置 */ + private String deviceDescription; + + /** 产品名称 */ + private String productName; + + /** 功能名称 */ + private String functionName; + + /** 数据值 */ + private String dataValue; + + /** 报警数据类型,0:老人异常数据,1:设备异常数据 */ + private Integer alertDataType; + + /** 语音通知状态,0:关闭,1:开启 */ + private Integer voiceNotifyStatus; + + /** 报警通知类型,0:解除报警,1:报警 */ + private Integer notifyType; + + /** + * 是否全员通知
+ * 智能床位的报警消息是全员通知,对于护理员和固定设备维护人员不是全员通知 + */ + private Boolean isAllConsumer; +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/BedVo.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/BedVo.java new file mode 100644 index 0000000..892e58d --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/BedVo.java @@ -0,0 +1,53 @@ +package com.zzyl.nursing.vo; + +import com.zzyl.common.core.domain.entity.SysUser; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +@Data +@ApiModel("床位Vo") +public class BedVo { + + @ApiModelProperty(value = "床位ID") + private Long id; + + /** + * 床位号 + */ + @ApiModelProperty(value = "床位号") + private String bedNumber; + + /** + * 床位状态: 未入住0, 已入住1 入住申请中2 + */ + @ApiModelProperty(value = "床位状态: 未入住0, 已入住1 入住申请中2") + private Integer bedStatus; + + /** + * 房间ID + */ + @ApiModelProperty(value = "房间ID") + private Long roomId; + + /** + * 老人姓名 + */ + @ApiModelProperty(value = "老人姓名") + private String ename; + + /** + * 老人id + */ + @ApiModelProperty(value = "老人id") + private Long elderId; + + @ApiModelProperty(value = "护理员") + private List userVos; + + @ApiModelProperty(value = "设备列表") + private List deviceVos; + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/CheckInConfigVo.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/CheckInConfigVo.java new file mode 100644 index 0000000..3d05013 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/CheckInConfigVo.java @@ -0,0 +1,40 @@ +package com.zzyl.nursing.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.zzyl.common.annotation.Excel; +import com.zzyl.nursing.domain.CheckInConfig; +import io.swagger.annotations.ApiModel; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 入住配置VO + * + * @Author: Zhy + * @Date: 2025-02-25 + **/ +@ApiModel(value = "入住配置VO") +@Data +public class CheckInConfigVo extends CheckInConfig { + + /** + * 入住开始时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "入住开始时间", width = 30, dateFormat = "yyyy-MM-dd") + private LocalDateTime startDate; + + /** + * 入住结束时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "入住结束时间", width = 30, dateFormat = "yyyy-MM-dd") + private LocalDateTime endDate; + + /** + * 入住床位 + */ + @Excel(name = "入住床位") + private String bedNumber; +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/CheckInDetailVo.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/CheckInDetailVo.java new file mode 100644 index 0000000..2097a79 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/CheckInDetailVo.java @@ -0,0 +1,43 @@ +package com.zzyl.nursing.vo; + +import com.zzyl.nursing.domain.Contract; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +/** + * 入住详情响应模型 + * + * @Author: Zhy + * @Date: 2025-02-25 + **/ +@ApiModel(description = "入住详情响应模型") +@Data +public class CheckInDetailVo { + /** + * 老人信息 + */ + @ApiModelProperty(value = "老人响应信息") + private CheckInElderVo checkInElderVo; + + /** + * 家属信息 + */ + @ApiModelProperty(value = "家属响应信息") + private List elderFamilyVoList; + + /** + * 入住配置 + */ + @ApiModelProperty(value = "入住配置响应信息") + private CheckInConfigVo checkInConfigVo; + + /** + * 签约办理 + */ + @ApiModelProperty(value = "签约办理响应信息") + private Contract contract; + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/CheckInElderVo.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/CheckInElderVo.java new file mode 100644 index 0000000..52e0148 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/CheckInElderVo.java @@ -0,0 +1,82 @@ +package com.zzyl.nursing.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 老人入住请求模型 + * + * @Author: Zhy + * @Date: 2025-02-25 + **/ +@ApiModel(description = "老人入住请求模型") +@Data +public class CheckInElderVo { + + /** + * 老人id + */ + @ApiModelProperty(value = "老人id") + private Long id; + + /** + * 姓名 + */ + @ApiModelProperty(value = "姓名") + private String name; + + /** + * 身份证号 + */ + @ApiModelProperty(value = "身份证号") + private String idCardNo; + + /** + * 出生日期,格式:yyyy-MM-dd + */ + @ApiModelProperty(value = "出生日期,格式:yyyy-MM-dd") + private String birthday; + + /** + * 性别,0:男,1:女,2:未知 + */ + @ApiModelProperty(value = "性别,0:男,1:女,2:未知") + private Integer sex; + + /** + * 手机号 + */ + @ApiModelProperty(value = "手机号") + private String phone; + + /** + * 家庭住址 + */ + @ApiModelProperty(value = "家庭住址") + private String address; + + /** + * 一寸照片 + */ + @ApiModelProperty(value = "一寸照片") + private String image; + + /** + * 身份证国徽面 + */ + @ApiModelProperty(value = "身份证国徽面") + private String idCardNationalEmblemImg; + + /** + * 身份证人像面 + */ + @ApiModelProperty(value = "身份证人像面") + private String idCardPortraitImg; + + /** + * 年龄 + */ + private Integer age; + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/DeviceDetailVo.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/DeviceDetailVo.java new file mode 100644 index 0000000..0d36fbb --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/DeviceDetailVo.java @@ -0,0 +1,90 @@ +package com.zzyl.nursing.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 设备详情响应模型 + * + * @author Zhy + * @version 1.0 + * @date 2025-03-06 15:14 + */ +@Data +@ApiModel("设备详情响应模型") +public class DeviceDetailVo { + + /** 设备id */ + @ApiModelProperty(value = "设备id") + private Long id; + + /** 物联网设备id */ + @ApiModelProperty(value = "物联网设备id") + private String iotId; + + /** 设备名称 */ + @ApiModelProperty(value = "设备名称") + private String deviceName; + + /** 设备标识码 */ + @ApiModelProperty(value = "设备标识码") + private String nodeId; + + /** 设备秘钥 */ + @ApiModelProperty(value = "设备秘钥") + private String secret; + + /** 产品id */ + @ApiModelProperty(value = "产品id") + public String productKey; + + /** 产品名称 */ + @ApiModelProperty(value = "产品名称") + public String productName; + + /** 位置类型 0 随身设备 1固定设备 */ + @ApiModelProperty(value = "位置类型 0 随身设备 1固定设备") + private Integer locationType; + + /** 绑定位置,如果是随身设备为老人id,如果是固定设备为位置的最后一级id */ + @ApiModelProperty(value = "绑定位置,如果是随身设备为老人id,如果是固定设备为位置的最后一级id") + private Long bindingLocation; + + + /** 接入位置 */ + @ApiModelProperty(value = "接入位置") + private String remark; + + /** + * 设备状态,ONLINE:设备在线,OFFLINE:设备离线,ABNORMAL:设备异常,INACTIVE:设备未激活,FROZEN:设备冻结 + */ + @ApiModelProperty(value = "设备状态,ONLINE:设备在线,OFFLINE:设备离线,ABNORMAL:设备异常,INACTIVE:设备未激活,FROZEN:设备冻结") + private String deviceStatus; + + /** 激活时间 */ + @ApiModelProperty(value = "激活时间,格式:yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private LocalDateTime activeTime; + + /** 创建时间 */ + @ApiModelProperty(value = "创建时间,格式:yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private LocalDateTime createTime; + + /** 创建人id */ + @ApiModelProperty(value = "创建人id") + private Long createBy; + + /** 创建人名称 */ + @ApiModelProperty(value = "创建人名称") + private String creator; + + /** 位置备注 */ + @ApiModelProperty(value = "位置备注") + private String deviceDescription; + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/DeviceInfo.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/DeviceInfo.java new file mode 100644 index 0000000..ba31e72 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/DeviceInfo.java @@ -0,0 +1,32 @@ +package com.zzyl.nursing.vo; + +import com.zzyl.nursing.domain.DeviceData; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +@ApiModel("设备信息响应模型") +@Data +public class DeviceInfo { + + @ApiModelProperty(value = "主键") + private Long id; + + @ApiModelProperty(value = "物联网设备ID") + private String iotId; + + @ApiModelProperty(value = "设备名称") + private String deviceName; + + @ApiModelProperty(value = "产品key") + public String productKey; + + @ApiModelProperty(value = "产品名称") + public String productName; + + @ApiModelProperty(value = "设备数据") + private List deviceDataVos; + +} \ No newline at end of file diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/DevicePropertyVo.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/DevicePropertyVo.java new file mode 100644 index 0000000..bfd4276 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/DevicePropertyVo.java @@ -0,0 +1,20 @@ +package com.zzyl.nursing.vo; + +import com.zzyl.nursing.domain.DevicePropertyList; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * @author Chihiro + * @date 2025-03-14 12:03 + * @version v1.0 + */ +@AllArgsConstructor +@Data +@NoArgsConstructor +public class DevicePropertyVo implements Serializable { + private DevicePropertyList list; +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/DeviceReportDataVo.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/DeviceReportDataVo.java new file mode 100644 index 0000000..91a646f --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/DeviceReportDataVo.java @@ -0,0 +1,38 @@ +package com.zzyl.nursing.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +/** + * 设备上报数据VO + * + * @author Zhy + * @version 1.0 + * @date 2025-03-06 16:25 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel(value = "设备上报数据VO") +public class DeviceReportDataVo { + + /** 属性名 */ + @ApiModelProperty(value = "属性名") + private String functionId; + + /** 上报时间 */ + @ApiModelProperty(value = "上报时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private LocalDateTime eventTime; + + /** 上报数据 */ + @ApiModelProperty(value = "上报数据") + private String value; + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/ElderFamilyVo.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/ElderFamilyVo.java new file mode 100644 index 0000000..11879df --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/ElderFamilyVo.java @@ -0,0 +1,36 @@ +package com.zzyl.nursing.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 老人家属信息 + * + * @Author: Zhy + * @Date: 2025-02-25 + **/ +@ApiModel(description = "老人家属信息") +@Data +public class ElderFamilyVo { + + /** + * 姓名 + */ + @ApiModelProperty(value = "姓名") + private String name; + + + /** + * 联系方式 + */ + @ApiModelProperty(value = "联系方式") + private String phone; + + /** + * 亲属关系 + */ + @ApiModelProperty(value = "亲属关系") + private String kinship; + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/FamilyMemberElderVo.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/FamilyMemberElderVo.java new file mode 100644 index 0000000..a914b0a --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/FamilyMemberElderVo.java @@ -0,0 +1,29 @@ +package com.zzyl.nursing.vo; + +import com.zzyl.common.core.domain.BaseEntity; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * @author Chihiro + * @date 2025-03-14 10:39 + * @version v1.0 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class FamilyMemberElderVo extends BaseEntity implements Serializable{ + private Long mid; + private String mremark; + private Long elderId; + private String name; + private String image; + private String bedNumber; + private String typeName; + private String iotId; + private String deviceName; + private String productKey; +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/FloorVo.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/FloorVo.java new file mode 100644 index 0000000..0a25793 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/FloorVo.java @@ -0,0 +1,22 @@ +package com.zzyl.nursing.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +@Data +public class FloorVo { + + private Long id; + + @ApiModelProperty(value = "楼层名称") + private String name; + + @ApiModelProperty(value = "楼层编号") + private Integer code; + + @ApiModelProperty(value = "房间") + private List roomVoList; + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/IotMsgBody.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/IotMsgBody.java new file mode 100644 index 0000000..c47b936 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/IotMsgBody.java @@ -0,0 +1,19 @@ +package com.zzyl.nursing.vo; + +import lombok.Data; + +import java.util.List; + +/** + * amqp消息-body部分 + * + * @author itcast + * @create 2024/1/16 10:00 + **/ +@Data +public class IotMsgBody { + /** + * 服务列表 + */ + private List services; +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/IotMsgHeader.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/IotMsgHeader.java new file mode 100644 index 0000000..69f2788 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/IotMsgHeader.java @@ -0,0 +1,37 @@ +package com.zzyl.nursing.vo; + +import lombok.Data; + +/** + * amqp消息-header部分 + * + * @author itcast + * @create 2024/1/16 10:00 + **/ +@Data +public class IotMsgHeader { + /** + * 物联网产品id + */ + private String productId; + + /** + * 物联网设备id + */ + private String deviceId; + + /** + * 设备标识码 + */ + private String nodeId; + + /** + * appid + */ + private String appId; + + /** + * 网关id + */ + private String gatewayId; +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/IotMsgNotifyData.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/IotMsgNotifyData.java new file mode 100644 index 0000000..51de876 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/IotMsgNotifyData.java @@ -0,0 +1,22 @@ +package com.zzyl.nursing.vo; + +import lombok.Data; + +/** + * amqp订阅消息 + * + * @author itcast + */ +@Data +public class IotMsgNotifyData { + + /** + * amqp消息-header部分 + */ + private IotMsgHeader header; + + /** + * amqp消息-body部分 + */ + private IotMsgBody body; +} \ No newline at end of file diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/IotMsgService.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/IotMsgService.java new file mode 100644 index 0000000..b832ae1 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/IotMsgService.java @@ -0,0 +1,29 @@ +package com.zzyl.nursing.vo; + +import lombok.Data; + +import java.util.Map; + +/** + * amqp消息-service模块 + * + * @author itcast + * @create 2024/1/16 10:22 + **/ +@Data +public class IotMsgService { + /** + * 服务id + */ + private String serviceId; + + /** + * 设备上报属性 + */ + private Map properties; + + /** + * 时间,格式:yyyyMMdd'T'HHmmss'Z' + */ + private String eventTime; +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/LoginVo.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/LoginVo.java new file mode 100644 index 0000000..0a99120 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/LoginVo.java @@ -0,0 +1,24 @@ +package com.zzyl.nursing.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * LoginVO + * + * @author Zhy + * @version 1.0 + * @date 2025-03-03 16:15 + */ +@Data +@ApiModel(value = "登录对象") +public class LoginVo { + + @ApiModelProperty(value = "JWT token") + private String token; + + @ApiModelProperty(value = "昵称") + private String nickName; + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/NursingLevelVo.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/NursingLevelVo.java new file mode 100644 index 0000000..e981f8e --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/NursingLevelVo.java @@ -0,0 +1,69 @@ +package com.zzyl.nursing.vo; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.zzyl.common.annotation.Excel; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 护理等级对象 nursing_level + * + * @author ruoyi + * @date 2024-10-04 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel("护理等级实体") +public class NursingLevelVo { + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @ApiModelProperty(value = "主键ID") + private Long id; + + /** + * 等级名称 + */ + @ApiModelProperty(value = "等级名称") + private String name; + + /** + * 护理计划ID + */ + @ApiModelProperty(value = "护理计划ID") + private Long lplanId; + + /** + * 护理费用 + */ + @ApiModelProperty(value = "护理费用") + private BigDecimal fee; + + /** + * 状态(0:禁用,1:启用) + */ + @ApiModelProperty(value = "状态") + private Integer status; + + /** + * 等级说明 + */ + @ApiModelProperty(value = "等级说明") + private String description; + + @ApiModelProperty(value = "创建时间") + private Date createTime; + + @ApiModelProperty(value = "关联护理计划名称") + private String planName; +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/NursingNameVo.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/NursingNameVo.java new file mode 100644 index 0000000..d51d019 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/NursingNameVo.java @@ -0,0 +1,17 @@ +package com.zzyl.nursing.vo; + +import lombok.Data; + +@Data +public class NursingNameVo { + + /** + * 老人id + */ + private Long elderId; + + /** + * 护理员姓名 + */ + private String nursingName; +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/NursingPlanVo.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/NursingPlanVo.java new file mode 100644 index 0000000..6ce1722 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/NursingPlanVo.java @@ -0,0 +1,33 @@ +package com.zzyl.nursing.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +@Data +@ApiModel(description = "护理计划") +public class NursingPlanVo { + + /** + * 护理计划id + */ + private Long id; + + /** + * 排序号 + */ + @ApiModelProperty(value = "护理计划排序号") + private Integer sortNo; + + @ApiModelProperty(value = "护理计划名称") + private String planName; + + @ApiModelProperty(value = "状态(0:禁用,1:启用)") + private Integer status; + + @ApiModelProperty(value = "护理计划项目计划列表") + List projectPlans; + +} \ No newline at end of file diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/NursingProjectPlanVo.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/NursingProjectPlanVo.java new file mode 100644 index 0000000..05ded64 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/NursingProjectPlanVo.java @@ -0,0 +1,30 @@ +package com.zzyl.nursing.vo; + +import com.zzyl.common.annotation.Excel; +import lombok.Data; + +@Data +public class NursingProjectPlanVo { + + /** 项目id */ + private String projectId; + + /** $column.columnComment */ + private Long id; + + /** 计划id */ + @Excel(name = "计划id") + private Long planId; + + /** 计划执行时间 */ + @Excel(name = "计划执行时间") + private String executeTime; + + /** 执行周期 0 天 1 周 2月 */ + @Excel(name = "执行周期 0 天 1 周 2月") + private String executeCycle; + + /** 执行频次 */ + @Excel(name = "执行频次") + private Long executeFrequency; +} \ No newline at end of file diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/NursingProjectVo.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/NursingProjectVo.java new file mode 100644 index 0000000..fabdab8 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/NursingProjectVo.java @@ -0,0 +1,16 @@ +package com.zzyl.nursing.vo; + +import lombok.Data; + +@Data +public class NursingProjectVo { + /** + * 项目名称 + */ + private String label; + + /** + * 项目ID + */ + private String value; +} \ No newline at end of file diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/NursingTaskVo.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/NursingTaskVo.java new file mode 100644 index 0000000..29b8cb0 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/NursingTaskVo.java @@ -0,0 +1,90 @@ +package com.zzyl.nursing.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.zzyl.common.annotation.Excel; +import com.zzyl.common.core.domain.BaseEntity; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * @author shd + * @version V1.0 + * @date 2025-03-14 14:23 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel("护理任务vo") +public class NursingTaskVo extends BaseEntity { + private static final long serialVersionUID = 1L; + + // id + @ApiModelProperty("id") + private Long id; + + // 护理员id + @Excel(name = "护理员id") + @ApiModelProperty("护理员id") + private String nursingId; + + // 项目id + @Excel(name = "项目id") + @ApiModelProperty("项目id") + private Integer projectId; + + // 护理项目名称 + @Excel(name = "护理项目名称") + @ApiModelProperty("护理项目名称") + private String projectName; + + // 老人id + @Excel(name = "老人id") + @ApiModelProperty("老人id") + private Long elderId; + + // 老人姓名 + @Excel(name = "老人姓名") + @ApiModelProperty("老人姓名") + private String elderName; + + // 床位编号 + @Excel(name = "床位编号") + @ApiModelProperty("床位编号") + private String bedNumber; + + // 预计服务时间 + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "预计服务时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty("预计服务时间") + private LocalDateTime estimatedServerTime; + + // 状态 1待执行 2已执行 3已关闭 + @Excel(name = "状态 1待执行 2已执行 3已关闭 ") + @ApiModelProperty("状态 1待执行 2已执行 3已关闭 ") + private Integer status; + + // 护理项目名称 + @Excel(name = "护理员姓名") + @ApiModelProperty("护理员姓名") + private List nursingName; + + private String nursingLevelName; + + private Integer age; + + private String updater; + + private String mark; + + private String taskImage; + + private LocalDateTime realServerTime; + + private String cancelReason; +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/ProductVo.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/ProductVo.java new file mode 100644 index 0000000..33edb0d --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/ProductVo.java @@ -0,0 +1,30 @@ +package com.zzyl.nursing.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 产品信息 + * + * @author Zhy + * @version 1.0 + * @date 2025-03-06 10:00 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel(value = "产品信息") +public class ProductVo { + + /** 产品ID */ + @ApiModelProperty(value = "产品ID") + private String productId; + + /** 产品名称 */ + @ApiModelProperty(value = "产品名称") + private String name; + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/RoomVo.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/RoomVo.java new file mode 100644 index 0000000..3401daf --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/RoomVo.java @@ -0,0 +1,37 @@ +package com.zzyl.nursing.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +@Data +@ApiModel("房间Vo") +public class RoomVo { + + @ApiModelProperty(value = "房间ID", required = true) + private Long id; + + @ApiModelProperty(value = "楼层名称", required = true) + private String floorName; + + @ApiModelProperty(value = "楼层ID", required = true) + private String floorId; + + @ApiModelProperty(value = "房间ID", required = true) + private String roomId; + + @ApiModelProperty(value = "房间编号", required = true) + private String code; + + @ApiModelProperty(value = "房间价格", required = true) + private String price; + + @ApiModelProperty(value = "床位列表", required = true) + private List bedVoList; + + @ApiModelProperty(value = "设备列表") + private List deviceVos; + +} \ No newline at end of file diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/TreeVo.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/TreeVo.java new file mode 100644 index 0000000..fff5cea --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/TreeVo.java @@ -0,0 +1,37 @@ +package com.zzyl.nursing.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * 树形结构VO + * + * @Author: Zhy + * @Date: 2025-02-25 9:51 + * @Version: 1.0 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel(description = "树形结构VO") +public class TreeVo { + + /** 菜单ID */ + @ApiModelProperty(value = "菜单ID") + private String value; + + /** 菜单名称 */ + @ApiModelProperty(value = "菜单名称") + private String label; + + + /** 子菜单 */ + @ApiModelProperty(value = "子菜单") + private List children; + +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/health/AbnormalDataVo.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/health/AbnormalDataVo.java new file mode 100644 index 0000000..4095187 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/health/AbnormalDataVo.java @@ -0,0 +1,40 @@ +package com.zzyl.nursing.vo.health; + +import lombok.Data; + +/** + * 异常数据类 + * @author itheima + */ +@Data +public class AbnormalDataVo { + /** + * 结论 + */ + private String conclusion; + /** + * 检查项目 + */ + private String examinationItem; + /** + * 结果 + */ + private String result; + /** + * 参考值 + */ + private String referenceValue; + /** + * 单位 + */ + private String unit; + /** + * 结果解释 + */ + private String interpret; + /** + * 建议 + */ + private String advice; + +} \ No newline at end of file diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/health/HealthAssessmentVo.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/health/HealthAssessmentVo.java new file mode 100644 index 0000000..0eb015e --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/health/HealthAssessmentVo.java @@ -0,0 +1,20 @@ +package com.zzyl.nursing.vo.health; + +import lombok.Data; + +/** + * 健康评估类 + * @author itheima + */ +@Data +public class HealthAssessmentVo { + /** + * 健康风险等级 + */ + private String riskLevel; + /** + * 健康指数 + */ + private double healthIndex; + +} \ No newline at end of file diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/health/HealthReportVo.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/health/HealthReportVo.java new file mode 100644 index 0000000..7c63e9b --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/health/HealthReportVo.java @@ -0,0 +1,40 @@ +package com.zzyl.nursing.vo.health; + +import lombok.Data; + +import java.util.List; + +/** + * 体检报告 + * @author itheima + */ +@Data +public class HealthReportVo { + + /** + * 体检日期 + */ + private String totalCheckDate; + /** + * 健康评估 + */ + private HealthAssessmentVo healthAssessment; + /** + * 风险分布 + */ + private RiskDistributionVo riskDistribution; + /** + * 异常数据列表 + */ + private List abnormalData; + + /** + * 健康系统分值 + */ + private SystemScore systemScore; + + /** + * 综合总结 + */ + private String summarize; +} diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/health/RiskDistributionVo.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/health/RiskDistributionVo.java new file mode 100644 index 0000000..ff60320 --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/health/RiskDistributionVo.java @@ -0,0 +1,32 @@ +package com.zzyl.nursing.vo.health; + +import lombok.Data; + +/** + * 风险分布类 + * @author itheima + */ +@Data +public class RiskDistributionVo { + /** + * 健康 + */ + private double healthy; + /** + * 警告 + */ + private double caution; + /** + * 风险 + */ + private double risk; + /** + * 危险 + */ + private double danger; + /** + * 严重危险 + */ + private double severeDanger; + +} \ No newline at end of file diff --git a/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/health/SystemScore.java b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/health/SystemScore.java new file mode 100644 index 0000000..f2b911a --- /dev/null +++ b/zzyl-nursing-platform/src/main/java/com/zzyl/nursing/vo/health/SystemScore.java @@ -0,0 +1,47 @@ +package com.zzyl.nursing.vo.health; + +import lombok.Data; + +@Data +public class SystemScore { + + /** + * 呼吸系统 + */ + private int breathingSystem; + + /** + * 消化系统 + */ + private int digestiveSystem; + + /** + * 内分泌系统 + */ + private int endocrineSystem; + + /** + * 免疫系统 + */ + private int immuneSystem; + + /** + * 循环系统 + */ + private int circulatorySystem; + + /** + * 泌尿系统 + */ + private int urinarySystem; + + /** + * 感觉系统 + */ + private int motionSystem; + + /** + * 感官系统 + */ + private int senseSystem; +} \ No newline at end of file diff --git a/zzyl-nursing-platform/src/main/resources/mapper/nursing/AlertDataMapper.xml b/zzyl-nursing-platform/src/main/resources/mapper/nursing/AlertDataMapper.xml new file mode 100644 index 0000000..9ea4de6 --- /dev/null +++ b/zzyl-nursing-platform/src/main/resources/mapper/nursing/AlertDataMapper.xml @@ -0,0 +1,175 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select id, iot_id, device_name, product_key, product_name, function_id, access_location, location_type, physical_location_type, device_description, data_value, alert_rule_id, alert_reason, processing_result, processor_id, processor_name, processing_time, type, status, user_id, create_time, update_time, create_by, update_by, remark from alert_data + + + + + + + + insert into alert_data + + iot_id, + device_name, + product_key, + product_name, + function_id, + access_location, + location_type, + physical_location_type, + device_description, + data_value, + alert_rule_id, + alert_reason, + processing_result, + processor_id, + processor_name, + processing_time, + type, + status, + user_id, + create_time, + update_time, + create_by, + update_by, + remark, + + + #{iotId}, + #{deviceName}, + #{productKey}, + #{productName}, + #{functionId}, + #{accessLocation}, + #{locationType}, + #{physicalLocationType}, + #{deviceDescription}, + #{dataValue}, + #{alertRuleId}, + #{alertReason}, + #{processingResult}, + #{processorId}, + #{processorName}, + #{processingTime}, + #{type}, + #{status}, + #{userId}, + #{createTime}, + #{updateTime}, + #{createBy}, + #{updateBy}, + #{remark}, + + + + + update alert_data + + iot_id = #{iotId}, + device_name = #{deviceName}, + product_key = #{productKey}, + product_name = #{productName}, + function_id = #{functionId}, + access_location = #{accessLocation}, + location_type = #{locationType}, + physical_location_type = #{physicalLocationType}, + device_description = #{deviceDescription}, + data_value = #{dataValue}, + alert_rule_id = #{alertRuleId}, + alert_reason = #{alertReason}, + processing_result = #{processingResult}, + processor_id = #{processorId}, + processor_name = #{processorName}, + processing_time = #{processingTime}, + type = #{type}, + status = #{status}, + user_id = #{userId}, + create_time = #{createTime}, + update_time = #{updateTime}, + create_by = #{createBy}, + update_by = #{updateBy}, + remark = #{remark}, + + where id = #{id} + + + + delete from alert_data where id = #{id} + + + + delete from alert_data where id in + + #{id} + + + + + \ No newline at end of file diff --git a/zzyl-nursing-platform/src/main/resources/mapper/nursing/AlertRuleMapper.xml b/zzyl-nursing-platform/src/main/resources/mapper/nursing/AlertRuleMapper.xml new file mode 100644 index 0000000..29cf0a5 --- /dev/null +++ b/zzyl-nursing-platform/src/main/resources/mapper/nursing/AlertRuleMapper.xml @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select id, product_key, product_name, module_id, module_name, function_name, function_id, iot_id, device_name, alert_data_type, alert_rule_name, operator, value, duration, alert_effective_period, alert_silent_period, status, create_time, update_time, create_by, update_by, remark from alert_rule + + + + + + + + insert into alert_rule + + product_key, + product_name, + module_id, + module_name, + function_name, + function_id, + iot_id, + device_name, + alert_data_type, + alert_rule_name, + operator, + value, + duration, + alert_effective_period, + alert_silent_period, + status, + create_time, + update_time, + create_by, + update_by, + remark, + + + #{productKey}, + #{productName}, + #{moduleId}, + #{moduleName}, + #{functionName}, + #{functionId}, + #{iotId}, + #{deviceName}, + #{alertDataType}, + #{alertRuleName}, + #{operator}, + #{value}, + #{duration}, + #{alertEffectivePeriod}, + #{alertSilentPeriod}, + #{status}, + #{createTime}, + #{updateTime}, + #{createBy}, + #{updateBy}, + #{remark}, + + + + + update alert_rule + + product_key = #{productKey}, + product_name = #{productName}, + module_id = #{moduleId}, + module_name = #{moduleName}, + function_name = #{functionName}, + function_id = #{functionId}, + iot_id = #{iotId}, + device_name = #{deviceName}, + alert_data_type = #{alertDataType}, + alert_rule_name = #{alertRuleName}, + operator = #{operator}, + value = #{value}, + duration = #{duration}, + alert_effective_period = #{alertEffectivePeriod}, + alert_silent_period = #{alertSilentPeriod}, + status = #{status}, + create_time = #{createTime}, + update_time = #{updateTime}, + create_by = #{createBy}, + update_by = #{updateBy}, + remark = #{remark}, + + where id = #{id} + + + + delete from alert_rule where id = #{id} + + + + delete from alert_rule where id in + + #{id} + + + \ No newline at end of file diff --git a/zzyl-nursing-platform/src/main/resources/mapper/nursing/BedMapper.xml b/zzyl-nursing-platform/src/main/resources/mapper/nursing/BedMapper.xml new file mode 100644 index 0000000..c52e0c3 --- /dev/null +++ b/zzyl-nursing-platform/src/main/resources/mapper/nursing/BedMapper.xml @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + select id, bed_number, bed_status, sort, room_id, create_time, update_time, create_by, update_by, remark from bed + + + + + + + + + + insert into bed + + bed_number, + bed_status, + sort, + room_id, + create_time, + update_time, + create_by, + update_by, + remark, + + + #{bedNumber}, + #{bedStatus}, + #{sort}, + #{roomId}, + #{createTime}, + #{updateTime}, + #{createBy}, + #{updateBy}, + #{remark}, + + + + + update bed + + bed_number = #{bedNumber}, + bed_status = #{bedStatus}, + sort = #{sort}, + room_id = #{roomId}, + create_time = #{createTime}, + update_time = #{updateTime}, + create_by = #{createBy}, + update_by = #{updateBy}, + remark = #{remark}, + + where id = #{id} + + + + delete from bed where id = #{id} + + + + delete from bed where id in + + #{id} + + + \ No newline at end of file diff --git a/zzyl-nursing-platform/src/main/resources/mapper/nursing/CheckInConfigMapper.xml b/zzyl-nursing-platform/src/main/resources/mapper/nursing/CheckInConfigMapper.xml new file mode 100644 index 0000000..a59060a --- /dev/null +++ b/zzyl-nursing-platform/src/main/resources/mapper/nursing/CheckInConfigMapper.xml @@ -0,0 +1,131 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + select id, check_in_id, nursing_level_id, nursing_level_name, fee_start_date, fee_end_date, deposit, nursing_fee, bed_fee, insurance_payment, government_subsidy, other_fees, sort_order, create_time, update_time, create_by, update_by, remark from check_in_config + + + + + + + + insert into check_in_config + + check_in_id, + nursing_level_id, + nursing_level_name, + fee_start_date, + fee_end_date, + deposit, + nursing_fee, + bed_fee, + insurance_payment, + government_subsidy, + other_fees, + sort_order, + create_time, + update_time, + create_by, + update_by, + remark, + + + #{checkInId}, + #{nursingLevelId}, + #{nursingLevelName}, + #{feeStartDate}, + #{feeEndDate}, + #{deposit}, + #{nursingFee}, + #{bedFee}, + #{insurancePayment}, + #{governmentSubsidy}, + #{otherFees}, + #{sortOrder}, + #{createTime}, + #{updateTime}, + #{createBy}, + #{updateBy}, + #{remark}, + + + + + update check_in_config + + check_in_id = #{checkInId}, + nursing_level_id = #{nursingLevelId}, + nursing_level_name = #{nursingLevelName}, + fee_start_date = #{feeStartDate}, + fee_end_date = #{feeEndDate}, + deposit = #{deposit}, + nursing_fee = #{nursingFee}, + bed_fee = #{bedFee}, + insurance_payment = #{insurancePayment}, + government_subsidy = #{governmentSubsidy}, + other_fees = #{otherFees}, + sort_order = #{sortOrder}, + create_time = #{createTime}, + update_time = #{updateTime}, + create_by = #{createBy}, + update_by = #{updateBy}, + remark = #{remark}, + + where id = #{id} + + + + delete from check_in_config where id = #{id} + + + + delete from check_in_config where id in + + #{id} + + + \ No newline at end of file diff --git a/zzyl-nursing-platform/src/main/resources/mapper/nursing/CheckInMapper.xml b/zzyl-nursing-platform/src/main/resources/mapper/nursing/CheckInMapper.xml new file mode 100644 index 0000000..20b41f6 --- /dev/null +++ b/zzyl-nursing-platform/src/main/resources/mapper/nursing/CheckInMapper.xml @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + select id, elder_name, elder_id, id_card_no, start_date, end_date, nursing_level_name, bed_number, status, sort_order, create_time, update_time, create_by, update_by, remark from check_in + + + + + + + + insert into check_in + + elder_name, + elder_id, + id_card_no, + start_date, + end_date, + nursing_level_name, + bed_number, + status, + sort_order, + create_time, + update_time, + create_by, + update_by, + remark, + + + #{elderName}, + #{elderId}, + #{idCardNo}, + #{startDate}, + #{endDate}, + #{nursingLevelName}, + #{bedNumber}, + #{status}, + #{sortOrder}, + #{createTime}, + #{updateTime}, + #{createBy}, + #{updateBy}, + #{remark}, + + + + + update check_in + + elder_name = #{elderName}, + elder_id = #{elderId}, + id_card_no = #{idCardNo}, + start_date = #{startDate}, + end_date = #{endDate}, + nursing_level_name = #{nursingLevelName}, + bed_number = #{bedNumber}, + status = #{status}, + sort_order = #{sortOrder}, + create_time = #{createTime}, + update_time = #{updateTime}, + create_by = #{createBy}, + update_by = #{updateBy}, + remark = #{remark}, + + where id = #{id} + + + + delete from check_in where id = #{id} + + + + delete from check_in where id in + + #{id} + + + + + + \ No newline at end of file diff --git a/zzyl-nursing-platform/src/main/resources/mapper/nursing/ContractMapper.xml b/zzyl-nursing-platform/src/main/resources/mapper/nursing/ContractMapper.xml new file mode 100644 index 0000000..d97bcda --- /dev/null +++ b/zzyl-nursing-platform/src/main/resources/mapper/nursing/ContractMapper.xml @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select id, elder_id, contract_name, contract_number, agreement_path, third_party_phone, third_party_name, elder_name, start_date, end_date, status, sign_date, termination_submitter, termination_date, termination_agreement_path, sort_order, create_time, update_time, create_by, update_by, remark from contract + + + + + + + + insert into contract + + elder_id, + contract_name, + contract_number, + agreement_path, + third_party_phone, + third_party_name, + elder_name, + start_date, + end_date, + status, + sign_date, + termination_submitter, + termination_date, + termination_agreement_path, + sort_order, + create_time, + update_time, + create_by, + update_by, + remark, + + + #{elderId}, + #{contractName}, + #{contractNumber}, + #{agreementPath}, + #{thirdPartyPhone}, + #{thirdPartyName}, + #{elderName}, + #{startDate}, + #{endDate}, + #{status}, + #{signDate}, + #{terminationSubmitter}, + #{terminationDate}, + #{terminationAgreementPath}, + #{sortOrder}, + #{createTime}, + #{updateTime}, + #{createBy}, + #{updateBy}, + #{remark}, + + + + + update contract + + elder_id = #{elderId}, + contract_name = #{contractName}, + contract_number = #{contractNumber}, + agreement_path = #{agreementPath}, + third_party_phone = #{thirdPartyPhone}, + third_party_name = #{thirdPartyName}, + elder_name = #{elderName}, + start_date = #{startDate}, + end_date = #{endDate}, + status = #{status}, + sign_date = #{signDate}, + termination_submitter = #{terminationSubmitter}, + termination_date = #{terminationDate}, + termination_agreement_path = #{terminationAgreementPath}, + sort_order = #{sortOrder}, + create_time = #{createTime}, + update_time = #{updateTime}, + create_by = #{createBy}, + update_by = #{updateBy}, + remark = #{remark}, + + where id = #{id} + + + + delete from contract where id = #{id} + + + + delete from contract where id in + + #{id} + + + + + + \ No newline at end of file diff --git a/zzyl-nursing-platform/src/main/resources/mapper/nursing/DeviceDataMapper.xml b/zzyl-nursing-platform/src/main/resources/mapper/nursing/DeviceDataMapper.xml new file mode 100644 index 0000000..bea30e0 --- /dev/null +++ b/zzyl-nursing-platform/src/main/resources/mapper/nursing/DeviceDataMapper.xml @@ -0,0 +1,146 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + select id, device_name, iot_id, product_key, product_name, function_id, access_location, location_type, physical_location_type, device_description, data_value, alarm_time, create_time, update_time, create_by, update_by, remark from device_data + + + + + + + + + + + + insert into device_data + + device_name, + iot_id, + product_key, + product_name, + function_id, + access_location, + location_type, + physical_location_type, + device_description, + data_value, + alarm_time, + create_time, + update_time, + create_by, + update_by, + remark, + + + #{deviceName}, + #{iotId}, + #{productKey}, + #{productName}, + #{functionId}, + #{accessLocation}, + #{locationType}, + #{physicalLocationType}, + #{deviceDescription}, + #{dataValue}, + #{alarmTime}, + #{createTime}, + #{updateTime}, + #{createBy}, + #{updateBy}, + #{remark}, + + + + + update device_data + + device_name = #{deviceName}, + iot_id = #{iotId}, + product_key = #{productKey}, + product_name = #{productName}, + function_id = #{functionId}, + access_location = #{accessLocation}, + location_type = #{locationType}, + physical_location_type = #{physicalLocationType}, + device_description = #{deviceDescription}, + data_value = #{dataValue}, + alarm_time = #{alarmTime}, + create_time = #{createTime}, + update_time = #{updateTime}, + create_by = #{createBy}, + update_by = #{updateBy}, + remark = #{remark}, + + where id = #{id} + + + + delete from device_data where id = #{id} + + + + delete from device_data where id in + + #{id} + + + \ No newline at end of file diff --git a/zzyl-nursing-platform/src/main/resources/mapper/nursing/DeviceMapper.xml b/zzyl-nursing-platform/src/main/resources/mapper/nursing/DeviceMapper.xml new file mode 100644 index 0000000..892fc1d --- /dev/null +++ b/zzyl-nursing-platform/src/main/resources/mapper/nursing/DeviceMapper.xml @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + select id, iot_id, secret, binding_location, location_type, physical_location_type, device_name, product_key, product_name, device_description, have_entrance_guard, create_time, update_time, create_by, node_id, update_by, remark from device + + + + + + + + insert into device + + iot_id, + secret, + binding_location, + location_type, + physical_location_type, + device_name, + product_key, + product_name, + device_description, + have_entrance_guard, + create_time, + update_time, + create_by, + node_id, + update_by, + remark, + + + #{iotId}, + #{secret}, + #{bindingLocation}, + #{locationType}, + #{physicalLocationType}, + #{deviceName}, + #{productKey}, + #{productName}, + #{deviceDescription}, + #{haveEntranceGuard}, + #{createTime}, + #{updateTime}, + #{createBy}, + #{nodeId}, + #{updateBy}, + #{remark}, + + + + + update device + + iot_id = #{iotId}, + secret = #{secret}, + binding_location = #{bindingLocation}, + location_type = #{locationType}, + physical_location_type = #{physicalLocationType}, + device_name = #{deviceName}, + product_key = #{productKey}, + product_name = #{productName}, + device_description = #{deviceDescription}, + have_entrance_guard = #{haveEntranceGuard}, + create_time = #{createTime}, + update_time = #{updateTime}, + create_by = #{createBy}, + node_id = #{nodeId}, + update_by = #{updateBy}, + remark = #{remark}, + + where id = #{id} + + + + delete from device where id = #{id} + + + + delete from device where id in + + #{id} + + + + + + + + \ No newline at end of file diff --git a/zzyl-nursing-platform/src/main/resources/mapper/nursing/ElderMapper.xml b/zzyl-nursing-platform/src/main/resources/mapper/nursing/ElderMapper.xml new file mode 100644 index 0000000..6810bfa --- /dev/null +++ b/zzyl-nursing-platform/src/main/resources/mapper/nursing/ElderMapper.xml @@ -0,0 +1,140 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + select id, name, image, id_card_no, sex, status, phone, birthday, address, id_card_national_emblem_img, id_card_portrait_img, create_time, update_time, create_by, update_by, remark, bed_number, bed_id from elder + + + + + + + + insert into elder + + name, + image, + id_card_no, + sex, + status, + phone, + birthday, + address, + id_card_national_emblem_img, + id_card_portrait_img, + create_time, + update_time, + create_by, + update_by, + remark, + bed_number, + bed_id, + + + #{name}, + #{image}, + #{idCardNo}, + #{sex}, + #{status}, + #{phone}, + #{birthday}, + #{address}, + #{idCardNationalEmblemImg}, + #{idCardPortraitImg}, + #{createTime}, + #{updateTime}, + #{createBy}, + #{updateBy}, + #{remark}, + #{bedNumber}, + #{bedId}, + + + + + update elder + + name = #{name}, + image = #{image}, + id_card_no = #{idCardNo}, + sex = #{sex}, + status = #{status}, + phone = #{phone}, + birthday = #{birthday}, + address = #{address}, + id_card_national_emblem_img = #{idCardNationalEmblemImg}, + id_card_portrait_img = #{idCardPortraitImg}, + create_time = #{createTime}, + update_time = #{updateTime}, + create_by = #{createBy}, + update_by = #{updateBy}, + remark = #{remark}, + bed_number = #{bedNumber}, + bed_id = #{bedId}, + + where id = #{id} + + + + delete from elder where id = #{id} + + + + delete from elder where id in + + #{id} + + + + + + \ No newline at end of file diff --git a/zzyl-nursing-platform/src/main/resources/mapper/nursing/FamilyMemberElderMapper.xml b/zzyl-nursing-platform/src/main/resources/mapper/nursing/FamilyMemberElderMapper.xml new file mode 100644 index 0000000..bf0eea7 --- /dev/null +++ b/zzyl-nursing-platform/src/main/resources/mapper/nursing/FamilyMemberElderMapper.xml @@ -0,0 +1,24 @@ + + + + + + INSERT INTO zzyl.family_member_elder(family_member_id, elder_id, remark, create_time) + VALUES (#{familyMemberId}, #{elderId}, #{remark}, #{createTime}) + + + + + + \ No newline at end of file diff --git a/zzyl-nursing-platform/src/main/resources/mapper/nursing/FamilyMemberMapper.xml b/zzyl-nursing-platform/src/main/resources/mapper/nursing/FamilyMemberMapper.xml new file mode 100644 index 0000000..b85291b --- /dev/null +++ b/zzyl-nursing-platform/src/main/resources/mapper/nursing/FamilyMemberMapper.xml @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + + + + select id, phone, name, avatar, open_id, gender, create_time, update_time, create_by, update_by, remark from family_member + + + + + + + + insert into family_member + + phone, + name, + avatar, + open_id, + gender, + create_time, + update_time, + create_by, + update_by, + remark, + + + #{phone}, + #{name}, + #{avatar}, + #{openId}, + #{gender}, + #{createTime}, + #{updateTime}, + #{createBy}, + #{updateBy}, + #{remark}, + + + + + update family_member + + phone = #{phone}, + name = #{name}, + avatar = #{avatar}, + open_id = #{openId}, + gender = #{gender}, + create_time = #{createTime}, + update_time = #{updateTime}, + create_by = #{createBy}, + update_by = #{updateBy}, + remark = #{remark}, + + where id = #{id} + + + + delete from family_member where id = #{id} + + + + delete from family_member where id in + + #{id} + + + \ No newline at end of file diff --git a/zzyl-nursing-platform/src/main/resources/mapper/nursing/FloorMapper.xml b/zzyl-nursing-platform/src/main/resources/mapper/nursing/FloorMapper.xml new file mode 100644 index 0000000..0e0dbd3 --- /dev/null +++ b/zzyl-nursing-platform/src/main/resources/mapper/nursing/FloorMapper.xml @@ -0,0 +1,149 @@ + + + + + + + + + + + + + + + + + select id, + name, + code, + create_time, + update_time, + create_by, + update_by, + remark + from floor + + + + + + + + insert into floor + + name, + code, + create_time, + update_time, + create_by, + update_by, + remark, + + + #{name}, + #{code}, + #{createTime}, + #{updateTime}, + #{createBy}, + #{updateBy}, + #{remark}, + + + + + update floor + + name = #{name}, + code = #{code}, + create_time = #{createTime}, + update_time = #{updateTime}, + create_by = #{createBy}, + update_by = #{updateBy}, + remark = #{remark}, + + where id = #{id} + + + + delete + from floor + where id = #{id} + + + + delete from floor where id in + + #{id} + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/zzyl-nursing-platform/src/main/resources/mapper/nursing/HealthAssessmentMapper.xml b/zzyl-nursing-platform/src/main/resources/mapper/nursing/HealthAssessmentMapper.xml new file mode 100644 index 0000000..18f583e --- /dev/null +++ b/zzyl-nursing-platform/src/main/resources/mapper/nursing/HealthAssessmentMapper.xml @@ -0,0 +1,161 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select id, elder_name, id_card, birth_date, age, gender, health_score, risk_level, suggestion_for_admission, nursing_level_name, admission_status, total_check_date, physical_exam_institution, physical_report_url, assessment_time, report_summary, disease_risk, abnormal_analysis, system_score, create_by, create_time, update_by, update_time, remark from health_assessment + + + + + + + + insert into health_assessment + + elder_name, + id_card, + birth_date, + age, + gender, + health_score, + risk_level, + suggestion_for_admission, + nursing_level_name, + admission_status, + total_check_date, + physical_exam_institution, + physical_report_url, + assessment_time, + report_summary, + disease_risk, + abnormal_analysis, + system_score, + create_by, + create_time, + update_by, + update_time, + remark, + + + #{elderName}, + #{idCard}, + #{birthDate}, + #{age}, + #{gender}, + #{healthScore}, + #{riskLevel}, + #{suggestionForAdmission}, + #{nursingLevelName}, + #{admissionStatus}, + #{totalCheckDate}, + #{physicalExamInstitution}, + #{physicalReportUrl}, + #{assessmentTime}, + #{reportSummary}, + #{diseaseRisk}, + #{abnormalAnalysis}, + #{systemScore}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{remark}, + + + + + update health_assessment + + elder_name = #{elderName}, + id_card = #{idCard}, + birth_date = #{birthDate}, + age = #{age}, + gender = #{gender}, + health_score = #{healthScore}, + risk_level = #{riskLevel}, + suggestion_for_admission = #{suggestionForAdmission}, + nursing_level_name = #{nursingLevelName}, + admission_status = #{admissionStatus}, + total_check_date = #{totalCheckDate}, + physical_exam_institution = #{physicalExamInstitution}, + physical_report_url = #{physicalReportUrl}, + assessment_time = #{assessmentTime}, + report_summary = #{reportSummary}, + disease_risk = #{diseaseRisk}, + abnormal_analysis = #{abnormalAnalysis}, + system_score = #{systemScore}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + remark = #{remark}, + + where id = #{id} + + + + delete from health_assessment where id = #{id} + + + + delete from health_assessment where id in + + #{id} + + + \ No newline at end of file diff --git a/zzyl-nursing-platform/src/main/resources/mapper/nursing/NursingLevelMapper.xml b/zzyl-nursing-platform/src/main/resources/mapper/nursing/NursingLevelMapper.xml new file mode 100644 index 0000000..9c7d4e7 --- /dev/null +++ b/zzyl-nursing-platform/src/main/resources/mapper/nursing/NursingLevelMapper.xml @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + + select id, name, lplan_id, fee, status, description, remark, create_time, update_time, create_by, update_by from nursing_level + + + + + + + + + + insert into nursing_level + + name, + lplan_id, + fee, + status, + description, + remark, + create_time, + update_time, + create_by, + update_by, + + + #{name}, + #{lplanId}, + #{fee}, + #{status}, + #{description}, + #{remark}, + #{createTime}, + #{updateTime}, + #{createBy}, + #{updateBy}, + + + + + update nursing_level + + name = #{name}, + lplan_id = #{lplanId}, + fee = #{fee}, + status = #{status}, + description = #{description}, + remark = #{remark}, + create_time = #{createTime}, + update_time = #{updateTime}, + create_by = #{createBy}, + update_by = #{updateBy}, + + where id = #{id} + + + + delete from nursing_level where id = #{id} + + + + delete from nursing_level where id in + + #{id} + + + \ No newline at end of file diff --git a/zzyl-nursing-platform/src/main/resources/mapper/nursing/NursingPlanMapper.xml b/zzyl-nursing-platform/src/main/resources/mapper/nursing/NursingPlanMapper.xml new file mode 100644 index 0000000..5854c65 --- /dev/null +++ b/zzyl-nursing-platform/src/main/resources/mapper/nursing/NursingPlanMapper.xml @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + select id, sort_no, plan_name, status, create_time, update_time, create_by, update_by, remark from nursing_plan + + + + + + + + insert into nursing_plan + + sort_no, + plan_name, + status, + create_time, + update_time, + create_by, + update_by, + remark, + + + #{sortNo}, + #{planName}, + #{status}, + #{createTime}, + #{updateTime}, + #{createBy}, + #{updateBy}, + #{remark}, + + + + + update nursing_plan + + sort_no = #{sortNo}, + plan_name = #{planName}, + status = #{status}, + create_time = #{createTime}, + update_time = #{updateTime}, + create_by = #{createBy}, + update_by = #{updateBy}, + remark = #{remark}, + + where id = #{id} + + + + delete from nursing_plan where id = #{id} + + + + delete from nursing_plan where id in + + #{id} + + + \ No newline at end of file diff --git a/zzyl-nursing-platform/src/main/resources/mapper/nursing/NursingProjectMapper.xml b/zzyl-nursing-platform/src/main/resources/mapper/nursing/NursingProjectMapper.xml new file mode 100644 index 0000000..9aa16c3 --- /dev/null +++ b/zzyl-nursing-platform/src/main/resources/mapper/nursing/NursingProjectMapper.xml @@ -0,0 +1,111 @@ + + + + + + + + + + + + + + + + + + + + + + select id, name, order_no, unit, price, image, nursing_requirement, status, create_by, update_by, remark, create_time, update_time from nursing_project + + + + + + + + insert into nursing_project + + name, + order_no, + unit, + price, + image, + nursing_requirement, + status, + create_by, + update_by, + remark, + create_time, + update_time, + + + #{name}, + #{orderNo}, + #{unit}, + #{price}, + #{image}, + #{nursingRequirement}, + #{status}, + #{createBy}, + #{updateBy}, + #{remark}, + #{createTime}, + #{updateTime}, + + + + + update nursing_project + + name = #{name}, + order_no = #{orderNo}, + unit = #{unit}, + price = #{price}, + image = #{image}, + nursing_requirement = #{nursingRequirement}, + status = #{status}, + create_by = #{createBy}, + update_by = #{updateBy}, + remark = #{remark}, + create_time = #{createTime}, + update_time = #{updateTime}, + + where id = #{id} + + + + delete from nursing_project where id = #{id} + + + + delete from nursing_project where id in + + #{id} + + + + + + diff --git a/zzyl-nursing-platform/src/main/resources/mapper/nursing/NursingProjectPlanMapper.xml b/zzyl-nursing-platform/src/main/resources/mapper/nursing/NursingProjectPlanMapper.xml new file mode 100644 index 0000000..3c5791d --- /dev/null +++ b/zzyl-nursing-platform/src/main/resources/mapper/nursing/NursingProjectPlanMapper.xml @@ -0,0 +1,112 @@ + + + + + + + + + + + + + + + + + + + + select id, plan_id, project_id, execute_time, execute_cycle, execute_frequency, create_time, update_time, create_by, update_by, remark from nursing_project_plan + + + + + + + + insert into nursing_project_plan + + plan_id, + project_id, + execute_time, + execute_cycle, + execute_frequency, + create_time, + update_time, + create_by, + update_by, + remark, + + + #{planId}, + #{projectId}, + #{executeTime}, + #{executeCycle}, + #{executeFrequency}, + #{createTime}, + #{updateTime}, + #{createBy}, + #{updateBy}, + #{remark}, + + + + + insert into nursing_project_plan(plan_id, project_id, execute_time, execute_cycle, execute_frequency, + create_time, remark) values + + (#{planId}, #{item.projectId}, #{item.executeTime}, #{item.executeCycle}, #{item.executeFrequency}, + sysdate(), #{item.remark}) + + + + + update nursing_project_plan + + plan_id = #{planId}, + project_id = #{projectId}, + execute_time = #{executeTime}, + execute_cycle = #{executeCycle}, + execute_frequency = #{executeFrequency}, + create_time = #{createTime}, + update_time = #{updateTime}, + create_by = #{createBy}, + update_by = #{updateBy}, + remark = #{remark}, + + where id = #{id} + + + + delete from nursing_project_plan where id = #{id} + + + + delete from nursing_project_plan where id in + + #{id} + + + + + delete from nursing_project_plan where plan_id in + + #{id} + + + \ No newline at end of file diff --git a/zzyl-nursing-platform/src/main/resources/mapper/nursing/NursingTaskMapper.xml b/zzyl-nursing-platform/src/main/resources/mapper/nursing/NursingTaskMapper.xml new file mode 100644 index 0000000..e4408bc --- /dev/null +++ b/zzyl-nursing-platform/src/main/resources/mapper/nursing/NursingTaskMapper.xml @@ -0,0 +1,131 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + select id, nursing_id, project_id, project_name, elder_id, elder_name, bed_number, estimated_server_time, real_server_time, mark, cancel_reason, status, task_image, create_time, update_time, create_by, update_by, remark from nursing_task + + + + + + + + insert into nursing_task + + nursing_id, + project_id, + project_name, + elder_id, + elder_name, + bed_number, + estimated_server_time, + real_server_time, + mark, + cancel_reason, + status, + task_image, + create_time, + update_time, + create_by, + update_by, + remark, + + + #{nursingId}, + #{projectId}, + #{projectName}, + #{elderId}, + #{elderName}, + #{bedNumber}, + #{estimatedServerTime}, + #{realServerTime}, + #{mark}, + #{cancelReason}, + #{status}, + #{taskImage}, + #{createTime}, + #{updateTime}, + #{createBy}, + #{updateBy}, + #{remark}, + + + + + update nursing_task + + nursing_id = #{nursingId}, + project_id = #{projectId}, + project_name = #{projectName}, + elder_id = #{elderId}, + elder_name = #{elderName}, + bed_number = #{bedNumber}, + estimated_server_time = #{estimatedServerTime}, + real_server_time = #{realServerTime}, + mark = #{mark}, + cancel_reason = #{cancelReason}, + status = #{status}, + task_image = #{taskImage}, + create_time = #{createTime}, + update_time = #{updateTime}, + create_by = #{createBy}, + update_by = #{updateBy}, + remark = #{remark}, + + where id = #{id} + + + + delete from nursing_task where id = #{id} + + + + delete from nursing_task where id in + + #{id} + + + \ No newline at end of file diff --git a/zzyl-nursing-platform/src/main/resources/mapper/nursing/RoomMapper.xml b/zzyl-nursing-platform/src/main/resources/mapper/nursing/RoomMapper.xml new file mode 100644 index 0000000..3f7d7e6 --- /dev/null +++ b/zzyl-nursing-platform/src/main/resources/mapper/nursing/RoomMapper.xml @@ -0,0 +1,244 @@ + + + + + + + + + + + + + + + + + + + + select id, code, sort, type_name, floor_id, create_time, update_time, is_deleted, create_by, update_by, remark from room + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + insert into room + + code, + sort, + type_name, + floor_id, + create_time, + update_time, + is_deleted, + create_by, + update_by, + remark, + + + #{code}, + #{sort}, + #{typeName}, + #{floorId}, + #{createTime}, + #{updateTime}, + #{isDeleted}, + #{createBy}, + #{updateBy}, + #{remark}, + + + + + update room + + code = #{code}, + sort = #{sort}, + type_name = #{typeName}, + floor_id = #{floorId}, + create_time = #{createTime}, + update_time = #{updateTime}, + is_deleted = #{isDeleted}, + create_by = #{createBy}, + update_by = #{updateBy}, + remark = #{remark}, + + where id = #{id} + + + + delete from room where id = #{id} + + + + delete from room where id in + + #{id} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/zzyl-nursing-platform/src/main/resources/mapper/nursing/RoomTypeMapper.xml b/zzyl-nursing-platform/src/main/resources/mapper/nursing/RoomTypeMapper.xml new file mode 100644 index 0000000..ee1b88f --- /dev/null +++ b/zzyl-nursing-platform/src/main/resources/mapper/nursing/RoomTypeMapper.xml @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + select id, name, bed_count, price, introduction, photo, status, create_time, update_time, create_by, update_by, remark from room_type + + + + + + + + insert into room_type + + name, + bed_count, + price, + introduction, + photo, + status, + create_time, + update_time, + create_by, + update_by, + remark, + + + #{name}, + #{bedCount}, + #{price}, + #{introduction}, + #{photo}, + #{status}, + #{createTime}, + #{updateTime}, + #{createBy}, + #{updateBy}, + #{remark}, + + + + + update room_type + + name = #{name}, + bed_count = #{bedCount}, + price = #{price}, + introduction = #{introduction}, + photo = #{photo}, + status = #{status}, + create_time = #{createTime}, + update_time = #{updateTime}, + create_by = #{createBy}, + update_by = #{updateBy}, + remark = #{remark}, + + where id = #{id} + + + + delete from room_type where id = #{id} + + + + delete from room_type where id in + + #{id} + + + \ No newline at end of file diff --git a/zzyl-nursing-platform/src/main/resources/mapper/nursing/member/MemberReservationMapper.xml b/zzyl-nursing-platform/src/main/resources/mapper/nursing/member/MemberReservationMapper.xml new file mode 100644 index 0000000..52dd55e --- /dev/null +++ b/zzyl-nursing-platform/src/main/resources/mapper/nursing/member/MemberReservationMapper.xml @@ -0,0 +1,112 @@ + + + + + + + + + + + + + + + + + + + + + select id, name, mobile, time, visitor, type, status, create_time, update_time, create_by, update_by, remark from reservation + + + + + + + + insert into reservation + + name, + mobile, + time, + visitor, + type, + status, + create_time, + update_time, + create_by, + update_by, + remark, + + + #{name}, + #{mobile}, + #{time}, + #{visitor}, + #{type}, + #{status}, + #{createTime}, + #{updateTime}, + #{createBy}, + #{updateBy}, + #{remark}, + + + + + update reservation + + name = #{name}, + mobile = #{mobile}, + time = #{time}, + visitor = #{visitor}, + type = #{type}, + status = #{status}, + create_time = #{createTime}, + update_time = #{updateTime}, + create_by = #{createBy}, + update_by = #{updateBy}, + remark = #{remark}, + + where id = #{id} + + + + delete from reservation where id = #{id} + + + + delete from reservation where id in + + #{id} + + + + + + + update reservation set status = #{status} where id = #{id} + + + + \ No newline at end of file diff --git a/zzyl-nursing-platform/src/test/java/com/zzyl/HttpTest.java b/zzyl-nursing-platform/src/test/java/com/zzyl/HttpTest.java new file mode 100644 index 0000000..14d44eb --- /dev/null +++ b/zzyl-nursing-platform/src/test/java/com/zzyl/HttpTest.java @@ -0,0 +1,61 @@ +package com.zzyl; +import java.math.BigDecimal; +import java.util.Date; + +import cn.hutool.json.JSONUtil; +import com.google.common.collect.Maps; + +import cn.hutool.http.HttpResponse; +import cn.hutool.http.HttpUtil; +import com.zzyl.common.utils.http.HttpUtils; +import com.zzyl.nursing.domain.NursingProject; +import org.junit.jupiter.api.Test; + +import java.util.HashMap; +import java.util.Map; + +/** + * HttpUtil 测试类 + * + * @author Zhy + * @version 1.0 + * @date 2025-03-03 22:23 + */ +public class HttpTest { + + @Test + public void testGet1() { + String content = HttpUtil.get("https://www.baidu.com"); + System.out.println(content); + } + + @Test + public void testGet2() { + Map params = Map.of("pageNum", 1, "pageSize", 5); + HttpResponse response = HttpUtil.createGet("http://localhost:9003/nursing/project/list") + .header("authorization", "Bearer eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6IjEyNGYwYzY4LWI1YjgtNDhiNS05OWVmLTIyYTRkOTcyNzk0NCJ9.Oz1sjYOHAmB6Xh28ORpVDEmCnBzt3lapV3O3LcQ7NTdPsggafdm9_BcHYcADwlimBQMG7_CRSko3AmmHNGxq1w") + .form(params) + .execute(); + System.out.println(response.body()); + } + + @Test + public void testPost() { + NursingProject nursingProject = new NursingProject(); + nursingProject.setName("测试计划222"); + nursingProject.setOrderNo(1); + nursingProject.setUnit("次"); + nursingProject.setPrice(new BigDecimal("50")); + nursingProject.setImage("222.jpg"); + nursingProject.setNursingRequirement("测试计划222测试计划222"); + nursingProject.setStatus(1); + + HttpResponse response = HttpUtil.createPost("http://localhost:9003/nursing/project").header( + "authorization", + "Bearer eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6IjEyNGYwYzY4LWI1YjgtNDhiNS05OWVmLTIyYTRkOTcyNzk0NCJ9.Oz1sjYOHAmB6Xh28ORpVDEmCnBzt3lapV3O3LcQ7NTdPsggafdm9_BcHYcADwlimBQMG7_CRSko3AmmHNGxq1w" + ).body(JSONUtil.toJsonStr(nursingProject)).execute(); + + System.out.println(response.body()); + } + +} diff --git a/zzyl-oss/pom.xml b/zzyl-oss/pom.xml new file mode 100644 index 0000000..5205ac6 --- /dev/null +++ b/zzyl-oss/pom.xml @@ -0,0 +1,32 @@ + + + 4.0.0 + + com.zzyl + zzyl + 3.8.8 + + + zzyl-oss + + + 11 + 11 + UTF-8 + + + + + com.aliyun.oss + aliyun-sdk-oss + + + + com.zzyl + zzyl-common + + + + \ No newline at end of file diff --git a/zzyl-oss/src/main/java/com/zzyl/oss/AliyunOssProperties.java b/zzyl-oss/src/main/java/com/zzyl/oss/AliyunOssProperties.java new file mode 100644 index 0000000..006933a --- /dev/null +++ b/zzyl-oss/src/main/java/com/zzyl/oss/AliyunOssProperties.java @@ -0,0 +1,69 @@ +package com.zzyl.oss; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * @author ghy + * @version V1.0 + * @date 2025-01-13 15:07 + */ +@Component +@ConfigurationProperties(prefix = "aliyun.oss") +public class AliyunOssProperties { + + private String domain; + private String endpoint; + private String bucketName; + private String region; + private String accessKeyId; + private String secretAccessKey; + + public String getDomain() { + return domain; + } + + public void setDomain(String domain) { + this.domain = domain; + } + + public String getEndpoint() { + return endpoint; + } + + public void setEndpoint(String endpoint) { + this.endpoint = endpoint; + } + + public String getBucketName() { + return bucketName; + } + + public void setBucketName(String bucketName) { + this.bucketName = bucketName; + } + + public String getRegion() { + return region; + } + + public void setRegion(String region) { + this.region = region; + } + + public String getAccessKeyId() { + return accessKeyId; + } + + public void setAccessKeyId(String accessKeyId) { + this.accessKeyId = accessKeyId; + } + + public String getSecretAccessKey() { + return secretAccessKey; + } + + public void setSecretAccessKey(String secretAccessKey) { + this.secretAccessKey = secretAccessKey; + } +} diff --git a/zzyl-oss/src/main/java/com/zzyl/oss/AliyunOssUtils.java b/zzyl-oss/src/main/java/com/zzyl/oss/AliyunOssUtils.java new file mode 100644 index 0000000..538896c --- /dev/null +++ b/zzyl-oss/src/main/java/com/zzyl/oss/AliyunOssUtils.java @@ -0,0 +1,71 @@ +package com.zzyl.oss; + +import cn.hutool.core.lang.UUID; +import cn.hutool.core.util.ObjUtil; +import cn.hutool.core.util.StrUtil; +import com.aliyun.oss.OSS; +import com.aliyun.oss.OSSClientBuilder; +import com.aliyun.oss.common.auth.CredentialsProvider; +import com.aliyun.oss.common.auth.DefaultCredentialProvider; +import com.zzyl.common.utils.DateUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.web.multipart.MultipartFile; + +@Component +public class AliyunOssUtils { + + @Autowired + private AliyunOssProperties aliyunOssProperties; + + /** + * 阿里云OSS 上传文件 + * @param file + * @return 返回文件上传到服务器的路径 + */ + public String uploadFile(MultipartFile file) { + + String accessKeyId = aliyunOssProperties.getAccessKeyId(); + String secretAccessKey = aliyunOssProperties.getSecretAccessKey(); + String endpoint = aliyunOssProperties.getEndpoint(); + String region = aliyunOssProperties.getRegion(); + String bucketName = aliyunOssProperties.getBucketName(); + String domain = aliyunOssProperties.getDomain(); + + // 1.参数校验 + if(ObjUtil.isEmpty(file) || file.isEmpty()){ + throw new RuntimeException("上传文件不能为空"); + } + String filename = file.getOriginalFilename(); + if(StrUtil.isEmpty(filename)){ + throw new RuntimeException("上传文件名错误!"); + } + String path = null; + OSS ossClient = null; + try { + CredentialsProvider credentialsProvider = new DefaultCredentialProvider(accessKeyId, secretAccessKey); + ossClient = OSSClientBuilder.create() + .endpoint(endpoint) + .credentialsProvider(credentialsProvider) + .credentialsProvider(credentialsProvider) + .region(region) + .build(); + //.jpg + String suffix = filename.substring(filename.lastIndexOf(".")); + filename = DateUtils.datePath() + "/" + + UUID.randomUUID().toString().replaceAll("-", "") + + suffix; + + ossClient.putObject(bucketName, filename, file.getInputStream()); + path = "https://" + bucketName + "." + domain + "/" + filename; + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (ossClient != null) { + ossClient.shutdown(); + } + } + return path; + } + +} \ No newline at end of file diff --git a/zzyl-quartz/pom.xml b/zzyl-quartz/pom.xml new file mode 100644 index 0000000..bd8a10d --- /dev/null +++ b/zzyl-quartz/pom.xml @@ -0,0 +1,40 @@ + + + + zzyl + com.zzyl + 3.8.8 + + 4.0.0 + + zzyl-quartz + + + quartz定时任务 + + + + + + + org.quartz-scheduler + quartz + + + com.mchange + c3p0 + + + + + + + com.zzyl + zzyl-common + + + + + \ No newline at end of file diff --git a/zzyl-quartz/src/main/java/com/zzyl/quartz/config/ScheduleConfig.java b/zzyl-quartz/src/main/java/com/zzyl/quartz/config/ScheduleConfig.java new file mode 100644 index 0000000..bc9f2c6 --- /dev/null +++ b/zzyl-quartz/src/main/java/com/zzyl/quartz/config/ScheduleConfig.java @@ -0,0 +1,57 @@ +//package com.zzyl.quartz.config; +// +//import org.springframework.context.annotation.Bean; +//import org.springframework.context.annotation.Configuration; +//import org.springframework.scheduling.quartz.SchedulerFactoryBean; +//import javax.sql.DataSource; +//import java.util.Properties; +// +///** +// * 定时任务配置(单机部署建议删除此类和qrtz数据库表,默认走内存会最高效) +// * +// * @author ruoyi +// */ +//@Configuration +//public class ScheduleConfig +//{ +// @Bean +// public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource) +// { +// SchedulerFactoryBean factory = new SchedulerFactoryBean(); +// factory.setDataSource(dataSource); +// +// // quartz参数 +// Properties prop = new Properties(); +// prop.put("org.quartz.scheduler.instanceName", "RuoyiScheduler"); +// prop.put("org.quartz.scheduler.instanceId", "AUTO"); +// // 线程池配置 +// prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool"); +// prop.put("org.quartz.threadPool.threadCount", "20"); +// prop.put("org.quartz.threadPool.threadPriority", "5"); +// // JobStore配置 +// prop.put("org.quartz.jobStore.class", "org.springframework.scheduling.quartz.LocalDataSourceJobStore"); +// // 集群配置 +// prop.put("org.quartz.jobStore.isClustered", "true"); +// prop.put("org.quartz.jobStore.clusterCheckinInterval", "15000"); +// prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "10"); +// prop.put("org.quartz.jobStore.txIsolationLevelSerializable", "true"); +// +// // sqlserver 启用 +// // prop.put("org.quartz.jobStore.selectWithLockSQL", "SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?"); +// prop.put("org.quartz.jobStore.misfireThreshold", "12000"); +// prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_"); +// factory.setQuartzProperties(prop); +// +// factory.setSchedulerName("RuoyiScheduler"); +// // 延时启动 +// factory.setStartupDelay(1); +// factory.setApplicationContextSchedulerContextKey("applicationContextKey"); +// // 可选,QuartzScheduler +// // 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了 +// factory.setOverwriteExistingJobs(true); +// // 设置自动启动,默认为true +// factory.setAutoStartup(true); +// +// return factory; +// } +//} diff --git a/zzyl-quartz/src/main/java/com/zzyl/quartz/controller/SysJobController.java b/zzyl-quartz/src/main/java/com/zzyl/quartz/controller/SysJobController.java new file mode 100644 index 0000000..88718ee --- /dev/null +++ b/zzyl-quartz/src/main/java/com/zzyl/quartz/controller/SysJobController.java @@ -0,0 +1,185 @@ +package com.zzyl.quartz.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.quartz.SchedulerException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.zzyl.common.annotation.Log; +import com.zzyl.common.constant.Constants; +import com.zzyl.common.core.controller.BaseController; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.core.page.TableDataInfo; +import com.zzyl.common.enums.BusinessType; +import com.zzyl.common.exception.job.TaskException; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.common.utils.poi.ExcelUtil; +import com.zzyl.quartz.domain.SysJob; +import com.zzyl.quartz.service.ISysJobService; +import com.zzyl.quartz.util.CronUtils; +import com.zzyl.quartz.util.ScheduleUtils; + +/** + * 调度任务信息操作处理 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/monitor/job") +public class SysJobController extends BaseController +{ + @Autowired + private ISysJobService jobService; + + /** + * 查询定时任务列表 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:list')") + @GetMapping("/list") + public TableDataInfo list(SysJob sysJob) + { + startPage(); + List list = jobService.selectJobList(sysJob); + return getDataTable(list); + } + + /** + * 导出定时任务列表 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:export')") + @Log(title = "定时任务", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, SysJob sysJob) + { + List list = jobService.selectJobList(sysJob); + ExcelUtil util = new ExcelUtil(SysJob.class); + util.exportExcel(response, list, "定时任务"); + } + + /** + * 获取定时任务详细信息 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:query')") + @GetMapping(value = "/{jobId}") + public AjaxResult getInfo(@PathVariable("jobId") Long jobId) + { + return success(jobService.selectJobById(jobId)); + } + + /** + * 新增定时任务 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:add')") + @Log(title = "定时任务", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody SysJob job) throws SchedulerException, TaskException + { + if (!CronUtils.isValid(job.getCronExpression())) + { + return error("新增任务'" + job.getJobName() + "'失败,Cron表达式不正确"); + } + else if (StringUtils.containsIgnoreCase(job.getInvokeTarget(), Constants.LOOKUP_RMI)) + { + return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'rmi'调用"); + } + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.LOOKUP_LDAP, Constants.LOOKUP_LDAPS })) + { + return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'ldap(s)'调用"); + } + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.HTTP, Constants.HTTPS })) + { + return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'http(s)'调用"); + } + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), Constants.JOB_ERROR_STR)) + { + return error("新增任务'" + job.getJobName() + "'失败,目标字符串存在违规"); + } + else if (!ScheduleUtils.whiteList(job.getInvokeTarget())) + { + return error("新增任务'" + job.getJobName() + "'失败,目标字符串不在白名单内"); + } + job.setCreateBy(getUsername()); + return toAjax(jobService.insertJob(job)); + } + + /** + * 修改定时任务 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:edit')") + @Log(title = "定时任务", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody SysJob job) throws SchedulerException, TaskException + { + if (!CronUtils.isValid(job.getCronExpression())) + { + return error("修改任务'" + job.getJobName() + "'失败,Cron表达式不正确"); + } + else if (StringUtils.containsIgnoreCase(job.getInvokeTarget(), Constants.LOOKUP_RMI)) + { + return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'rmi'调用"); + } + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.LOOKUP_LDAP, Constants.LOOKUP_LDAPS })) + { + return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'ldap(s)'调用"); + } + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.HTTP, Constants.HTTPS })) + { + return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'http(s)'调用"); + } + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), Constants.JOB_ERROR_STR)) + { + return error("修改任务'" + job.getJobName() + "'失败,目标字符串存在违规"); + } + else if (!ScheduleUtils.whiteList(job.getInvokeTarget())) + { + return error("修改任务'" + job.getJobName() + "'失败,目标字符串不在白名单内"); + } + job.setUpdateBy(getUsername()); + return toAjax(jobService.updateJob(job)); + } + + /** + * 定时任务状态修改 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:changeStatus')") + @Log(title = "定时任务", businessType = BusinessType.UPDATE) + @PutMapping("/changeStatus") + public AjaxResult changeStatus(@RequestBody SysJob job) throws SchedulerException + { + SysJob newJob = jobService.selectJobById(job.getJobId()); + newJob.setStatus(job.getStatus()); + return toAjax(jobService.changeStatus(newJob)); + } + + /** + * 定时任务立即执行一次 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:changeStatus')") + @Log(title = "定时任务", businessType = BusinessType.UPDATE) + @PutMapping("/run") + public AjaxResult run(@RequestBody SysJob job) throws SchedulerException + { + boolean result = jobService.run(job); + return result ? success() : error("任务不存在或已过期!"); + } + + /** + * 删除定时任务 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:remove')") + @Log(title = "定时任务", businessType = BusinessType.DELETE) + @DeleteMapping("/{jobIds}") + public AjaxResult remove(@PathVariable Long[] jobIds) throws SchedulerException, TaskException + { + jobService.deleteJobByIds(jobIds); + return success(); + } +} diff --git a/zzyl-quartz/src/main/java/com/zzyl/quartz/controller/SysJobLogController.java b/zzyl-quartz/src/main/java/com/zzyl/quartz/controller/SysJobLogController.java new file mode 100644 index 0000000..d2f153a --- /dev/null +++ b/zzyl-quartz/src/main/java/com/zzyl/quartz/controller/SysJobLogController.java @@ -0,0 +1,92 @@ +package com.zzyl.quartz.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.zzyl.common.annotation.Log; +import com.zzyl.common.core.controller.BaseController; +import com.zzyl.common.core.domain.AjaxResult; +import com.zzyl.common.core.page.TableDataInfo; +import com.zzyl.common.enums.BusinessType; +import com.zzyl.common.utils.poi.ExcelUtil; +import com.zzyl.quartz.domain.SysJobLog; +import com.zzyl.quartz.service.ISysJobLogService; + +/** + * 调度日志操作处理 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/monitor/jobLog") +public class SysJobLogController extends BaseController +{ + @Autowired + private ISysJobLogService jobLogService; + + /** + * 查询定时任务调度日志列表 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:list')") + @GetMapping("/list") + public TableDataInfo list(SysJobLog sysJobLog) + { + startPage(); + List list = jobLogService.selectJobLogList(sysJobLog); + return getDataTable(list); + } + + /** + * 导出定时任务调度日志列表 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:export')") + @Log(title = "任务调度日志", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, SysJobLog sysJobLog) + { + List list = jobLogService.selectJobLogList(sysJobLog); + ExcelUtil util = new ExcelUtil(SysJobLog.class); + util.exportExcel(response, list, "调度日志"); + } + + /** + * 根据调度编号获取详细信息 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:query')") + @GetMapping(value = "/{jobLogId}") + public AjaxResult getInfo(@PathVariable Long jobLogId) + { + return success(jobLogService.selectJobLogById(jobLogId)); + } + + + /** + * 删除定时任务调度日志 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:remove')") + @Log(title = "定时任务调度日志", businessType = BusinessType.DELETE) + @DeleteMapping("/{jobLogIds}") + public AjaxResult remove(@PathVariable Long[] jobLogIds) + { + return toAjax(jobLogService.deleteJobLogByIds(jobLogIds)); + } + + /** + * 清空定时任务调度日志 + */ + @PreAuthorize("@ss.hasPermi('monitor:job:remove')") + @Log(title = "调度日志", businessType = BusinessType.CLEAN) + @DeleteMapping("/clean") + public AjaxResult clean() + { + jobLogService.cleanJobLog(); + return success(); + } +} diff --git a/zzyl-quartz/src/main/java/com/zzyl/quartz/domain/SysJob.java b/zzyl-quartz/src/main/java/com/zzyl/quartz/domain/SysJob.java new file mode 100644 index 0000000..702dbc4 --- /dev/null +++ b/zzyl-quartz/src/main/java/com/zzyl/quartz/domain/SysJob.java @@ -0,0 +1,171 @@ +package com.zzyl.quartz.domain; + +import java.util.Date; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.zzyl.common.annotation.Excel; +import com.zzyl.common.annotation.Excel.ColumnType; +import com.zzyl.common.constant.ScheduleConstants; +import com.zzyl.common.core.domain.BaseEntity; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.quartz.util.CronUtils; + +/** + * 定时任务调度表 sys_job + * + * @author ruoyi + */ +public class SysJob extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 任务ID */ + @Excel(name = "任务序号", cellType = ColumnType.NUMERIC) + private Long jobId; + + /** 任务名称 */ + @Excel(name = "任务名称") + private String jobName; + + /** 任务组名 */ + @Excel(name = "任务组名") + private String jobGroup; + + /** 调用目标字符串 */ + @Excel(name = "调用目标字符串") + private String invokeTarget; + + /** cron执行表达式 */ + @Excel(name = "执行表达式 ") + private String cronExpression; + + /** cron计划策略 */ + @Excel(name = "计划策略 ", readConverterExp = "0=默认,1=立即触发执行,2=触发一次执行,3=不触发立即执行") + private String misfirePolicy = ScheduleConstants.MISFIRE_DEFAULT; + + /** 是否并发执行(0允许 1禁止) */ + @Excel(name = "并发执行", readConverterExp = "0=允许,1=禁止") + private String concurrent; + + /** 任务状态(0正常 1暂停) */ + @Excel(name = "任务状态", readConverterExp = "0=正常,1=暂停") + private String status; + + public Long getJobId() + { + return jobId; + } + + public void setJobId(Long jobId) + { + this.jobId = jobId; + } + + @NotBlank(message = "任务名称不能为空") + @Size(min = 0, max = 64, message = "任务名称不能超过64个字符") + public String getJobName() + { + return jobName; + } + + public void setJobName(String jobName) + { + this.jobName = jobName; + } + + public String getJobGroup() + { + return jobGroup; + } + + public void setJobGroup(String jobGroup) + { + this.jobGroup = jobGroup; + } + + @NotBlank(message = "调用目标字符串不能为空") + @Size(min = 0, max = 500, message = "调用目标字符串长度不能超过500个字符") + public String getInvokeTarget() + { + return invokeTarget; + } + + public void setInvokeTarget(String invokeTarget) + { + this.invokeTarget = invokeTarget; + } + + @NotBlank(message = "Cron执行表达式不能为空") + @Size(min = 0, max = 255, message = "Cron执行表达式不能超过255个字符") + public String getCronExpression() + { + return cronExpression; + } + + public void setCronExpression(String cronExpression) + { + this.cronExpression = cronExpression; + } + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + public Date getNextValidTime() + { + if (StringUtils.isNotEmpty(cronExpression)) + { + return CronUtils.getNextExecution(cronExpression); + } + return null; + } + + public String getMisfirePolicy() + { + return misfirePolicy; + } + + public void setMisfirePolicy(String misfirePolicy) + { + this.misfirePolicy = misfirePolicy; + } + + public String getConcurrent() + { + return concurrent; + } + + public void setConcurrent(String concurrent) + { + this.concurrent = concurrent; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("jobId", getJobId()) + .append("jobName", getJobName()) + .append("jobGroup", getJobGroup()) + .append("cronExpression", getCronExpression()) + .append("nextValidTime", getNextValidTime()) + .append("misfirePolicy", getMisfirePolicy()) + .append("concurrent", getConcurrent()) + .append("status", getStatus()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/zzyl-quartz/src/main/java/com/zzyl/quartz/domain/SysJobLog.java b/zzyl-quartz/src/main/java/com/zzyl/quartz/domain/SysJobLog.java new file mode 100644 index 0000000..7af734d --- /dev/null +++ b/zzyl-quartz/src/main/java/com/zzyl/quartz/domain/SysJobLog.java @@ -0,0 +1,155 @@ +package com.zzyl.quartz.domain; + +import java.util.Date; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.zzyl.common.annotation.Excel; +import com.zzyl.common.core.domain.BaseEntity; + +/** + * 定时任务调度日志表 sys_job_log + * + * @author ruoyi + */ +public class SysJobLog extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** ID */ + @Excel(name = "日志序号") + private Long jobLogId; + + /** 任务名称 */ + @Excel(name = "任务名称") + private String jobName; + + /** 任务组名 */ + @Excel(name = "任务组名") + private String jobGroup; + + /** 调用目标字符串 */ + @Excel(name = "调用目标字符串") + private String invokeTarget; + + /** 日志信息 */ + @Excel(name = "日志信息") + private String jobMessage; + + /** 执行状态(0正常 1失败) */ + @Excel(name = "执行状态", readConverterExp = "0=正常,1=失败") + private String status; + + /** 异常信息 */ + @Excel(name = "异常信息") + private String exceptionInfo; + + /** 开始时间 */ + private Date startTime; + + /** 停止时间 */ + private Date stopTime; + + public Long getJobLogId() + { + return jobLogId; + } + + public void setJobLogId(Long jobLogId) + { + this.jobLogId = jobLogId; + } + + public String getJobName() + { + return jobName; + } + + public void setJobName(String jobName) + { + this.jobName = jobName; + } + + public String getJobGroup() + { + return jobGroup; + } + + public void setJobGroup(String jobGroup) + { + this.jobGroup = jobGroup; + } + + public String getInvokeTarget() + { + return invokeTarget; + } + + public void setInvokeTarget(String invokeTarget) + { + this.invokeTarget = invokeTarget; + } + + public String getJobMessage() + { + return jobMessage; + } + + public void setJobMessage(String jobMessage) + { + this.jobMessage = jobMessage; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + public String getExceptionInfo() + { + return exceptionInfo; + } + + public void setExceptionInfo(String exceptionInfo) + { + this.exceptionInfo = exceptionInfo; + } + + public Date getStartTime() + { + return startTime; + } + + public void setStartTime(Date startTime) + { + this.startTime = startTime; + } + + public Date getStopTime() + { + return stopTime; + } + + public void setStopTime(Date stopTime) + { + this.stopTime = stopTime; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("jobLogId", getJobLogId()) + .append("jobName", getJobName()) + .append("jobGroup", getJobGroup()) + .append("jobMessage", getJobMessage()) + .append("status", getStatus()) + .append("exceptionInfo", getExceptionInfo()) + .append("startTime", getStartTime()) + .append("stopTime", getStopTime()) + .toString(); + } +} diff --git a/zzyl-quartz/src/main/java/com/zzyl/quartz/mapper/SysJobLogMapper.java b/zzyl-quartz/src/main/java/com/zzyl/quartz/mapper/SysJobLogMapper.java new file mode 100644 index 0000000..bf2e41d --- /dev/null +++ b/zzyl-quartz/src/main/java/com/zzyl/quartz/mapper/SysJobLogMapper.java @@ -0,0 +1,64 @@ +package com.zzyl.quartz.mapper; + +import java.util.List; +import com.zzyl.quartz.domain.SysJobLog; + +/** + * 调度任务日志信息 数据层 + * + * @author ruoyi + */ +public interface SysJobLogMapper +{ + /** + * 获取quartz调度器日志的计划任务 + * + * @param jobLog 调度日志信息 + * @return 调度任务日志集合 + */ + public List selectJobLogList(SysJobLog jobLog); + + /** + * 查询所有调度任务日志 + * + * @return 调度任务日志列表 + */ + public List selectJobLogAll(); + + /** + * 通过调度任务日志ID查询调度信息 + * + * @param jobLogId 调度任务日志ID + * @return 调度任务日志对象信息 + */ + public SysJobLog selectJobLogById(Long jobLogId); + + /** + * 新增任务日志 + * + * @param jobLog 调度日志信息 + * @return 结果 + */ + public int insertJobLog(SysJobLog jobLog); + + /** + * 批量删除调度日志信息 + * + * @param logIds 需要删除的数据ID + * @return 结果 + */ + public int deleteJobLogByIds(Long[] logIds); + + /** + * 删除任务日志 + * + * @param jobId 调度日志ID + * @return 结果 + */ + public int deleteJobLogById(Long jobId); + + /** + * 清空任务日志 + */ + public void cleanJobLog(); +} diff --git a/zzyl-quartz/src/main/java/com/zzyl/quartz/mapper/SysJobMapper.java b/zzyl-quartz/src/main/java/com/zzyl/quartz/mapper/SysJobMapper.java new file mode 100644 index 0000000..fbb28dd --- /dev/null +++ b/zzyl-quartz/src/main/java/com/zzyl/quartz/mapper/SysJobMapper.java @@ -0,0 +1,67 @@ +package com.zzyl.quartz.mapper; + +import java.util.List; +import com.zzyl.quartz.domain.SysJob; + +/** + * 调度任务信息 数据层 + * + * @author ruoyi + */ +public interface SysJobMapper +{ + /** + * 查询调度任务日志集合 + * + * @param job 调度信息 + * @return 操作日志集合 + */ + public List selectJobList(SysJob job); + + /** + * 查询所有调度任务 + * + * @return 调度任务列表 + */ + public List selectJobAll(); + + /** + * 通过调度ID查询调度任务信息 + * + * @param jobId 调度ID + * @return 角色对象信息 + */ + public SysJob selectJobById(Long jobId); + + /** + * 通过调度ID删除调度任务信息 + * + * @param jobId 调度ID + * @return 结果 + */ + public int deleteJobById(Long jobId); + + /** + * 批量删除调度任务信息 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteJobByIds(Long[] ids); + + /** + * 修改调度任务信息 + * + * @param job 调度任务信息 + * @return 结果 + */ + public int updateJob(SysJob job); + + /** + * 新增调度任务信息 + * + * @param job 调度任务信息 + * @return 结果 + */ + public int insertJob(SysJob job); +} diff --git a/zzyl-quartz/src/main/java/com/zzyl/quartz/service/ISysJobLogService.java b/zzyl-quartz/src/main/java/com/zzyl/quartz/service/ISysJobLogService.java new file mode 100644 index 0000000..02e905d --- /dev/null +++ b/zzyl-quartz/src/main/java/com/zzyl/quartz/service/ISysJobLogService.java @@ -0,0 +1,56 @@ +package com.zzyl.quartz.service; + +import java.util.List; +import com.zzyl.quartz.domain.SysJobLog; + +/** + * 定时任务调度日志信息信息 服务层 + * + * @author ruoyi + */ +public interface ISysJobLogService +{ + /** + * 获取quartz调度器日志的计划任务 + * + * @param jobLog 调度日志信息 + * @return 调度任务日志集合 + */ + public List selectJobLogList(SysJobLog jobLog); + + /** + * 通过调度任务日志ID查询调度信息 + * + * @param jobLogId 调度任务日志ID + * @return 调度任务日志对象信息 + */ + public SysJobLog selectJobLogById(Long jobLogId); + + /** + * 新增任务日志 + * + * @param jobLog 调度日志信息 + */ + public void addJobLog(SysJobLog jobLog); + + /** + * 批量删除调度日志信息 + * + * @param logIds 需要删除的日志ID + * @return 结果 + */ + public int deleteJobLogByIds(Long[] logIds); + + /** + * 删除任务日志 + * + * @param jobId 调度日志ID + * @return 结果 + */ + public int deleteJobLogById(Long jobId); + + /** + * 清空任务日志 + */ + public void cleanJobLog(); +} diff --git a/zzyl-quartz/src/main/java/com/zzyl/quartz/service/ISysJobService.java b/zzyl-quartz/src/main/java/com/zzyl/quartz/service/ISysJobService.java new file mode 100644 index 0000000..38926ac --- /dev/null +++ b/zzyl-quartz/src/main/java/com/zzyl/quartz/service/ISysJobService.java @@ -0,0 +1,102 @@ +package com.zzyl.quartz.service; + +import java.util.List; +import org.quartz.SchedulerException; +import com.zzyl.common.exception.job.TaskException; +import com.zzyl.quartz.domain.SysJob; + +/** + * 定时任务调度信息信息 服务层 + * + * @author ruoyi + */ +public interface ISysJobService +{ + /** + * 获取quartz调度器的计划任务 + * + * @param job 调度信息 + * @return 调度任务集合 + */ + public List selectJobList(SysJob job); + + /** + * 通过调度任务ID查询调度信息 + * + * @param jobId 调度任务ID + * @return 调度任务对象信息 + */ + public SysJob selectJobById(Long jobId); + + /** + * 暂停任务 + * + * @param job 调度信息 + * @return 结果 + */ + public int pauseJob(SysJob job) throws SchedulerException; + + /** + * 恢复任务 + * + * @param job 调度信息 + * @return 结果 + */ + public int resumeJob(SysJob job) throws SchedulerException; + + /** + * 删除任务后,所对应的trigger也将被删除 + * + * @param job 调度信息 + * @return 结果 + */ + public int deleteJob(SysJob job) throws SchedulerException; + + /** + * 批量删除调度信息 + * + * @param jobIds 需要删除的任务ID + * @return 结果 + */ + public void deleteJobByIds(Long[] jobIds) throws SchedulerException; + + /** + * 任务调度状态修改 + * + * @param job 调度信息 + * @return 结果 + */ + public int changeStatus(SysJob job) throws SchedulerException; + + /** + * 立即运行任务 + * + * @param job 调度信息 + * @return 结果 + */ + public boolean run(SysJob job) throws SchedulerException; + + /** + * 新增任务 + * + * @param job 调度信息 + * @return 结果 + */ + public int insertJob(SysJob job) throws SchedulerException, TaskException; + + /** + * 更新任务 + * + * @param job 调度信息 + * @return 结果 + */ + public int updateJob(SysJob job) throws SchedulerException, TaskException; + + /** + * 校验cron表达式是否有效 + * + * @param cronExpression 表达式 + * @return 结果 + */ + public boolean checkCronExpressionIsValid(String cronExpression); +} diff --git a/zzyl-quartz/src/main/java/com/zzyl/quartz/service/impl/SysJobLogServiceImpl.java b/zzyl-quartz/src/main/java/com/zzyl/quartz/service/impl/SysJobLogServiceImpl.java new file mode 100644 index 0000000..97061f6 --- /dev/null +++ b/zzyl-quartz/src/main/java/com/zzyl/quartz/service/impl/SysJobLogServiceImpl.java @@ -0,0 +1,87 @@ +package com.zzyl.quartz.service.impl; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.zzyl.quartz.domain.SysJobLog; +import com.zzyl.quartz.mapper.SysJobLogMapper; +import com.zzyl.quartz.service.ISysJobLogService; + +/** + * 定时任务调度日志信息 服务层 + * + * @author ruoyi + */ +@Service +public class SysJobLogServiceImpl implements ISysJobLogService +{ + @Autowired + private SysJobLogMapper jobLogMapper; + + /** + * 获取quartz调度器日志的计划任务 + * + * @param jobLog 调度日志信息 + * @return 调度任务日志集合 + */ + @Override + public List selectJobLogList(SysJobLog jobLog) + { + return jobLogMapper.selectJobLogList(jobLog); + } + + /** + * 通过调度任务日志ID查询调度信息 + * + * @param jobLogId 调度任务日志ID + * @return 调度任务日志对象信息 + */ + @Override + public SysJobLog selectJobLogById(Long jobLogId) + { + return jobLogMapper.selectJobLogById(jobLogId); + } + + /** + * 新增任务日志 + * + * @param jobLog 调度日志信息 + */ + @Override + public void addJobLog(SysJobLog jobLog) + { + jobLogMapper.insertJobLog(jobLog); + } + + /** + * 批量删除调度日志信息 + * + * @param logIds 需要删除的数据ID + * @return 结果 + */ + @Override + public int deleteJobLogByIds(Long[] logIds) + { + return jobLogMapper.deleteJobLogByIds(logIds); + } + + /** + * 删除任务日志 + * + * @param jobId 调度日志ID + */ + @Override + public int deleteJobLogById(Long jobId) + { + return jobLogMapper.deleteJobLogById(jobId); + } + + /** + * 清空任务日志 + */ + @Override + public void cleanJobLog() + { + jobLogMapper.cleanJobLog(); + } +} diff --git a/zzyl-quartz/src/main/java/com/zzyl/quartz/service/impl/SysJobServiceImpl.java b/zzyl-quartz/src/main/java/com/zzyl/quartz/service/impl/SysJobServiceImpl.java new file mode 100644 index 0000000..7754532 --- /dev/null +++ b/zzyl-quartz/src/main/java/com/zzyl/quartz/service/impl/SysJobServiceImpl.java @@ -0,0 +1,261 @@ +package com.zzyl.quartz.service.impl; + +import java.util.List; +import javax.annotation.PostConstruct; +import org.quartz.JobDataMap; +import org.quartz.JobKey; +import org.quartz.Scheduler; +import org.quartz.SchedulerException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import com.zzyl.common.constant.ScheduleConstants; +import com.zzyl.common.exception.job.TaskException; +import com.zzyl.quartz.domain.SysJob; +import com.zzyl.quartz.mapper.SysJobMapper; +import com.zzyl.quartz.service.ISysJobService; +import com.zzyl.quartz.util.CronUtils; +import com.zzyl.quartz.util.ScheduleUtils; + +/** + * 定时任务调度信息 服务层 + * + * @author ruoyi + */ +@Service +public class SysJobServiceImpl implements ISysJobService +{ + @Autowired + private Scheduler scheduler; + + @Autowired + private SysJobMapper jobMapper; + + /** + * 项目启动时,初始化定时器 主要是防止手动修改数据库导致未同步到定时任务处理(注:不能手动修改数据库ID和任务组名,否则会导致脏数据) + */ + @PostConstruct + public void init() throws SchedulerException, TaskException + { + scheduler.clear(); + List jobList = jobMapper.selectJobAll(); + for (SysJob job : jobList) + { + ScheduleUtils.createScheduleJob(scheduler, job); + } + } + + /** + * 获取quartz调度器的计划任务列表 + * + * @param job 调度信息 + * @return + */ + @Override + public List selectJobList(SysJob job) + { + return jobMapper.selectJobList(job); + } + + /** + * 通过调度任务ID查询调度信息 + * + * @param jobId 调度任务ID + * @return 调度任务对象信息 + */ + @Override + public SysJob selectJobById(Long jobId) + { + return jobMapper.selectJobById(jobId); + } + + /** + * 暂停任务 + * + * @param job 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int pauseJob(SysJob job) throws SchedulerException + { + Long jobId = job.getJobId(); + String jobGroup = job.getJobGroup(); + job.setStatus(ScheduleConstants.Status.PAUSE.getValue()); + int rows = jobMapper.updateJob(job); + if (rows > 0) + { + scheduler.pauseJob(ScheduleUtils.getJobKey(jobId, jobGroup)); + } + return rows; + } + + /** + * 恢复任务 + * + * @param job 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int resumeJob(SysJob job) throws SchedulerException + { + Long jobId = job.getJobId(); + String jobGroup = job.getJobGroup(); + job.setStatus(ScheduleConstants.Status.NORMAL.getValue()); + int rows = jobMapper.updateJob(job); + if (rows > 0) + { + scheduler.resumeJob(ScheduleUtils.getJobKey(jobId, jobGroup)); + } + return rows; + } + + /** + * 删除任务后,所对应的trigger也将被删除 + * + * @param job 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int deleteJob(SysJob job) throws SchedulerException + { + Long jobId = job.getJobId(); + String jobGroup = job.getJobGroup(); + int rows = jobMapper.deleteJobById(jobId); + if (rows > 0) + { + scheduler.deleteJob(ScheduleUtils.getJobKey(jobId, jobGroup)); + } + return rows; + } + + /** + * 批量删除调度信息 + * + * @param jobIds 需要删除的任务ID + * @return 结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteJobByIds(Long[] jobIds) throws SchedulerException + { + for (Long jobId : jobIds) + { + SysJob job = jobMapper.selectJobById(jobId); + deleteJob(job); + } + } + + /** + * 任务调度状态修改 + * + * @param job 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int changeStatus(SysJob job) throws SchedulerException + { + int rows = 0; + String status = job.getStatus(); + if (ScheduleConstants.Status.NORMAL.getValue().equals(status)) + { + rows = resumeJob(job); + } + else if (ScheduleConstants.Status.PAUSE.getValue().equals(status)) + { + rows = pauseJob(job); + } + return rows; + } + + /** + * 立即运行任务 + * + * @param job 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public boolean run(SysJob job) throws SchedulerException + { + boolean result = false; + Long jobId = job.getJobId(); + String jobGroup = job.getJobGroup(); + SysJob properties = selectJobById(job.getJobId()); + // 参数 + JobDataMap dataMap = new JobDataMap(); + dataMap.put(ScheduleConstants.TASK_PROPERTIES, properties); + JobKey jobKey = ScheduleUtils.getJobKey(jobId, jobGroup); + if (scheduler.checkExists(jobKey)) + { + result = true; + scheduler.triggerJob(jobKey, dataMap); + } + return result; + } + + /** + * 新增任务 + * + * @param job 调度信息 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int insertJob(SysJob job) throws SchedulerException, TaskException + { + job.setStatus(ScheduleConstants.Status.PAUSE.getValue()); + int rows = jobMapper.insertJob(job); + if (rows > 0) + { + ScheduleUtils.createScheduleJob(scheduler, job); + } + return rows; + } + + /** + * 更新任务的时间表达式 + * + * @param job 调度信息 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int updateJob(SysJob job) throws SchedulerException, TaskException + { + SysJob properties = selectJobById(job.getJobId()); + int rows = jobMapper.updateJob(job); + if (rows > 0) + { + updateSchedulerJob(job, properties.getJobGroup()); + } + return rows; + } + + /** + * 更新任务 + * + * @param job 任务对象 + * @param jobGroup 任务组名 + */ + public void updateSchedulerJob(SysJob job, String jobGroup) throws SchedulerException, TaskException + { + Long jobId = job.getJobId(); + // 判断是否存在 + JobKey jobKey = ScheduleUtils.getJobKey(jobId, jobGroup); + if (scheduler.checkExists(jobKey)) + { + // 防止创建时存在数据问题 先移除,然后在执行创建操作 + scheduler.deleteJob(jobKey); + } + ScheduleUtils.createScheduleJob(scheduler, job); + } + + /** + * 校验cron表达式是否有效 + * + * @param cronExpression 表达式 + * @return 结果 + */ + @Override + public boolean checkCronExpressionIsValid(String cronExpression) + { + return CronUtils.isValid(cronExpression); + } +} diff --git a/zzyl-quartz/src/main/java/com/zzyl/quartz/task/RyTask.java b/zzyl-quartz/src/main/java/com/zzyl/quartz/task/RyTask.java new file mode 100644 index 0000000..e654626 --- /dev/null +++ b/zzyl-quartz/src/main/java/com/zzyl/quartz/task/RyTask.java @@ -0,0 +1,28 @@ +package com.zzyl.quartz.task; + +import org.springframework.stereotype.Component; +import com.zzyl.common.utils.StringUtils; + +/** + * 定时任务调度测试 + * + * @author ruoyi + */ +@Component("ryTask") +public class RyTask +{ + public void ryMultipleParams(String s, Boolean b, Long l, Double d, Integer i) + { + System.out.println(StringUtils.format("执行多参方法: 字符串类型{},布尔类型{},长整型{},浮点型{},整形{}", s, b, l, d, i)); + } + + public void ryParams(String params) + { + System.out.println("执行有参方法:" + params); + } + + public void ryNoParams() + { + System.out.println("执行无参方法"); + } +} diff --git a/zzyl-quartz/src/main/java/com/zzyl/quartz/util/AbstractQuartzJob.java b/zzyl-quartz/src/main/java/com/zzyl/quartz/util/AbstractQuartzJob.java new file mode 100644 index 0000000..1cd32aa --- /dev/null +++ b/zzyl-quartz/src/main/java/com/zzyl/quartz/util/AbstractQuartzJob.java @@ -0,0 +1,107 @@ +package com.zzyl.quartz.util; + +import java.util.Date; +import org.quartz.Job; +import org.quartz.JobExecutionContext; +import org.quartz.JobExecutionException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.zzyl.common.constant.Constants; +import com.zzyl.common.constant.ScheduleConstants; +import com.zzyl.common.utils.ExceptionUtil; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.common.utils.bean.BeanUtils; +import com.zzyl.common.utils.spring.SpringUtils; +import com.zzyl.quartz.domain.SysJob; +import com.zzyl.quartz.domain.SysJobLog; +import com.zzyl.quartz.service.ISysJobLogService; + +/** + * 抽象quartz调用 + * + * @author ruoyi + */ +public abstract class AbstractQuartzJob implements Job +{ + private static final Logger log = LoggerFactory.getLogger(AbstractQuartzJob.class); + + /** + * 线程本地变量 + */ + private static ThreadLocal threadLocal = new ThreadLocal<>(); + + @Override + public void execute(JobExecutionContext context) throws JobExecutionException + { + SysJob sysJob = new SysJob(); + BeanUtils.copyBeanProp(sysJob, context.getMergedJobDataMap().get(ScheduleConstants.TASK_PROPERTIES)); + try + { + before(context, sysJob); + if (sysJob != null) + { + doExecute(context, sysJob); + } + after(context, sysJob, null); + } + catch (Exception e) + { + log.error("任务执行异常 - :", e); + after(context, sysJob, e); + } + } + + /** + * 执行前 + * + * @param context 工作执行上下文对象 + * @param sysJob 系统计划任务 + */ + protected void before(JobExecutionContext context, SysJob sysJob) + { + threadLocal.set(new Date()); + } + + /** + * 执行后 + * + * @param context 工作执行上下文对象 + * @param sysJob 系统计划任务 + */ + protected void after(JobExecutionContext context, SysJob sysJob, Exception e) + { + Date startTime = threadLocal.get(); + threadLocal.remove(); + + final SysJobLog sysJobLog = new SysJobLog(); + sysJobLog.setJobName(sysJob.getJobName()); + sysJobLog.setJobGroup(sysJob.getJobGroup()); + sysJobLog.setInvokeTarget(sysJob.getInvokeTarget()); + sysJobLog.setStartTime(startTime); + sysJobLog.setStopTime(new Date()); + long runMs = sysJobLog.getStopTime().getTime() - sysJobLog.getStartTime().getTime(); + sysJobLog.setJobMessage(sysJobLog.getJobName() + " 总共耗时:" + runMs + "毫秒"); + if (e != null) + { + sysJobLog.setStatus(Constants.FAIL); + String errorMsg = StringUtils.substring(ExceptionUtil.getExceptionMessage(e), 0, 2000); + sysJobLog.setExceptionInfo(errorMsg); + } + else + { + sysJobLog.setStatus(Constants.SUCCESS); + } + + // 写入数据库当中 + SpringUtils.getBean(ISysJobLogService.class).addJobLog(sysJobLog); + } + + /** + * 执行方法,由子类重载 + * + * @param context 工作执行上下文对象 + * @param sysJob 系统计划任务 + * @throws Exception 执行过程中的异常 + */ + protected abstract void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception; +} diff --git a/zzyl-quartz/src/main/java/com/zzyl/quartz/util/CronUtils.java b/zzyl-quartz/src/main/java/com/zzyl/quartz/util/CronUtils.java new file mode 100644 index 0000000..4e9350a --- /dev/null +++ b/zzyl-quartz/src/main/java/com/zzyl/quartz/util/CronUtils.java @@ -0,0 +1,63 @@ +package com.zzyl.quartz.util; + +import java.text.ParseException; +import java.util.Date; +import org.quartz.CronExpression; + +/** + * cron表达式工具类 + * + * @author ruoyi + * + */ +public class CronUtils +{ + /** + * 返回一个布尔值代表一个给定的Cron表达式的有效性 + * + * @param cronExpression Cron表达式 + * @return boolean 表达式是否有效 + */ + public static boolean isValid(String cronExpression) + { + return CronExpression.isValidExpression(cronExpression); + } + + /** + * 返回一个字符串值,表示该消息无效Cron表达式给出有效性 + * + * @param cronExpression Cron表达式 + * @return String 无效时返回表达式错误描述,如果有效返回null + */ + public static String getInvalidMessage(String cronExpression) + { + try + { + new CronExpression(cronExpression); + return null; + } + catch (ParseException pe) + { + return pe.getMessage(); + } + } + + /** + * 返回下一个执行时间根据给定的Cron表达式 + * + * @param cronExpression Cron表达式 + * @return Date 下次Cron表达式执行时间 + */ + public static Date getNextExecution(String cronExpression) + { + try + { + CronExpression cron = new CronExpression(cronExpression); + return cron.getNextValidTimeAfter(new Date(System.currentTimeMillis())); + } + catch (ParseException e) + { + throw new IllegalArgumentException(e.getMessage()); + } + } +} diff --git a/zzyl-quartz/src/main/java/com/zzyl/quartz/util/JobInvokeUtil.java b/zzyl-quartz/src/main/java/com/zzyl/quartz/util/JobInvokeUtil.java new file mode 100644 index 0000000..a150676 --- /dev/null +++ b/zzyl-quartz/src/main/java/com/zzyl/quartz/util/JobInvokeUtil.java @@ -0,0 +1,182 @@ +package com.zzyl.quartz.util; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.LinkedList; +import java.util.List; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.common.utils.spring.SpringUtils; +import com.zzyl.quartz.domain.SysJob; + +/** + * 任务执行工具 + * + * @author ruoyi + */ +public class JobInvokeUtil +{ + /** + * 执行方法 + * + * @param sysJob 系统任务 + */ + public static void invokeMethod(SysJob sysJob) throws Exception + { + String invokeTarget = sysJob.getInvokeTarget(); + String beanName = getBeanName(invokeTarget); + String methodName = getMethodName(invokeTarget); + List methodParams = getMethodParams(invokeTarget); + + if (!isValidClassName(beanName)) + { + Object bean = SpringUtils.getBean(beanName); + invokeMethod(bean, methodName, methodParams); + } + else + { + Object bean = Class.forName(beanName).getDeclaredConstructor().newInstance(); + invokeMethod(bean, methodName, methodParams); + } + } + + /** + * 调用任务方法 + * + * @param bean 目标对象 + * @param methodName 方法名称 + * @param methodParams 方法参数 + */ + private static void invokeMethod(Object bean, String methodName, List methodParams) + throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, + InvocationTargetException + { + if (StringUtils.isNotNull(methodParams) && methodParams.size() > 0) + { + Method method = bean.getClass().getMethod(methodName, getMethodParamsType(methodParams)); + method.invoke(bean, getMethodParamsValue(methodParams)); + } + else + { + Method method = bean.getClass().getMethod(methodName); + method.invoke(bean); + } + } + + /** + * 校验是否为为class包名 + * + * @param invokeTarget 名称 + * @return true是 false否 + */ + public static boolean isValidClassName(String invokeTarget) + { + return StringUtils.countMatches(invokeTarget, ".") > 1; + } + + /** + * 获取bean名称 + * + * @param invokeTarget 目标字符串 + * @return bean名称 + */ + public static String getBeanName(String invokeTarget) + { + String beanName = StringUtils.substringBefore(invokeTarget, "("); + return StringUtils.substringBeforeLast(beanName, "."); + } + + /** + * 获取bean方法 + * + * @param invokeTarget 目标字符串 + * @return method方法 + */ + public static String getMethodName(String invokeTarget) + { + String methodName = StringUtils.substringBefore(invokeTarget, "("); + return StringUtils.substringAfterLast(methodName, "."); + } + + /** + * 获取method方法参数相关列表 + * + * @param invokeTarget 目标字符串 + * @return method方法相关参数列表 + */ + public static List getMethodParams(String invokeTarget) + { + String methodStr = StringUtils.substringBetween(invokeTarget, "(", ")"); + if (StringUtils.isEmpty(methodStr)) + { + return null; + } + String[] methodParams = methodStr.split(",(?=([^\"']*[\"'][^\"']*[\"'])*[^\"']*$)"); + List classs = new LinkedList<>(); + for (int i = 0; i < methodParams.length; i++) + { + String str = StringUtils.trimToEmpty(methodParams[i]); + // String字符串类型,以'或"开头 + if (StringUtils.startsWithAny(str, "'", "\"")) + { + classs.add(new Object[] { StringUtils.substring(str, 1, str.length() - 1), String.class }); + } + // boolean布尔类型,等于true或者false + else if ("true".equalsIgnoreCase(str) || "false".equalsIgnoreCase(str)) + { + classs.add(new Object[] { Boolean.valueOf(str), Boolean.class }); + } + // long长整形,以L结尾 + else if (StringUtils.endsWith(str, "L")) + { + classs.add(new Object[] { Long.valueOf(StringUtils.substring(str, 0, str.length() - 1)), Long.class }); + } + // double浮点类型,以D结尾 + else if (StringUtils.endsWith(str, "D")) + { + classs.add(new Object[] { Double.valueOf(StringUtils.substring(str, 0, str.length() - 1)), Double.class }); + } + // 其他类型归类为整形 + else + { + classs.add(new Object[] { Integer.valueOf(str), Integer.class }); + } + } + return classs; + } + + /** + * 获取参数类型 + * + * @param methodParams 参数相关列表 + * @return 参数类型列表 + */ + public static Class[] getMethodParamsType(List methodParams) + { + Class[] classs = new Class[methodParams.size()]; + int index = 0; + for (Object[] os : methodParams) + { + classs[index] = (Class) os[1]; + index++; + } + return classs; + } + + /** + * 获取参数值 + * + * @param methodParams 参数相关列表 + * @return 参数值列表 + */ + public static Object[] getMethodParamsValue(List methodParams) + { + Object[] classs = new Object[methodParams.size()]; + int index = 0; + for (Object[] os : methodParams) + { + classs[index] = (Object) os[0]; + index++; + } + return classs; + } +} diff --git a/zzyl-quartz/src/main/java/com/zzyl/quartz/util/QuartzDisallowConcurrentExecution.java b/zzyl-quartz/src/main/java/com/zzyl/quartz/util/QuartzDisallowConcurrentExecution.java new file mode 100644 index 0000000..0fafb03 --- /dev/null +++ b/zzyl-quartz/src/main/java/com/zzyl/quartz/util/QuartzDisallowConcurrentExecution.java @@ -0,0 +1,21 @@ +package com.zzyl.quartz.util; + +import org.quartz.DisallowConcurrentExecution; +import org.quartz.JobExecutionContext; +import com.zzyl.quartz.domain.SysJob; + +/** + * 定时任务处理(禁止并发执行) + * + * @author ruoyi + * + */ +@DisallowConcurrentExecution +public class QuartzDisallowConcurrentExecution extends AbstractQuartzJob +{ + @Override + protected void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception + { + JobInvokeUtil.invokeMethod(sysJob); + } +} diff --git a/zzyl-quartz/src/main/java/com/zzyl/quartz/util/QuartzJobExecution.java b/zzyl-quartz/src/main/java/com/zzyl/quartz/util/QuartzJobExecution.java new file mode 100644 index 0000000..a903ef2 --- /dev/null +++ b/zzyl-quartz/src/main/java/com/zzyl/quartz/util/QuartzJobExecution.java @@ -0,0 +1,19 @@ +package com.zzyl.quartz.util; + +import org.quartz.JobExecutionContext; +import com.zzyl.quartz.domain.SysJob; + +/** + * 定时任务处理(允许并发执行) + * + * @author ruoyi + * + */ +public class QuartzJobExecution extends AbstractQuartzJob +{ + @Override + protected void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception + { + JobInvokeUtil.invokeMethod(sysJob); + } +} diff --git a/zzyl-quartz/src/main/java/com/zzyl/quartz/util/ScheduleUtils.java b/zzyl-quartz/src/main/java/com/zzyl/quartz/util/ScheduleUtils.java new file mode 100644 index 0000000..9ff2442 --- /dev/null +++ b/zzyl-quartz/src/main/java/com/zzyl/quartz/util/ScheduleUtils.java @@ -0,0 +1,141 @@ +package com.zzyl.quartz.util; + +import org.quartz.CronScheduleBuilder; +import org.quartz.CronTrigger; +import org.quartz.Job; +import org.quartz.JobBuilder; +import org.quartz.JobDetail; +import org.quartz.JobKey; +import org.quartz.Scheduler; +import org.quartz.SchedulerException; +import org.quartz.TriggerBuilder; +import org.quartz.TriggerKey; +import com.zzyl.common.constant.Constants; +import com.zzyl.common.constant.ScheduleConstants; +import com.zzyl.common.exception.job.TaskException; +import com.zzyl.common.exception.job.TaskException.Code; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.common.utils.spring.SpringUtils; +import com.zzyl.quartz.domain.SysJob; + +/** + * 定时任务工具类 + * + * @author ruoyi + * + */ +public class ScheduleUtils +{ + /** + * 得到quartz任务类 + * + * @param sysJob 执行计划 + * @return 具体执行任务类 + */ + private static Class getQuartzJobClass(SysJob sysJob) + { + boolean isConcurrent = "0".equals(sysJob.getConcurrent()); + return isConcurrent ? QuartzJobExecution.class : QuartzDisallowConcurrentExecution.class; + } + + /** + * 构建任务触发对象 + */ + public static TriggerKey getTriggerKey(Long jobId, String jobGroup) + { + return TriggerKey.triggerKey(ScheduleConstants.TASK_CLASS_NAME + jobId, jobGroup); + } + + /** + * 构建任务键对象 + */ + public static JobKey getJobKey(Long jobId, String jobGroup) + { + return JobKey.jobKey(ScheduleConstants.TASK_CLASS_NAME + jobId, jobGroup); + } + + /** + * 创建定时任务 + */ + public static void createScheduleJob(Scheduler scheduler, SysJob job) throws SchedulerException, TaskException + { + Class jobClass = getQuartzJobClass(job); + // 构建job信息 + Long jobId = job.getJobId(); + String jobGroup = job.getJobGroup(); + JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(getJobKey(jobId, jobGroup)).build(); + + // 表达式调度构建器 + CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression()); + cronScheduleBuilder = handleCronScheduleMisfirePolicy(job, cronScheduleBuilder); + + // 按新的cronExpression表达式构建一个新的trigger + CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(jobId, jobGroup)) + .withSchedule(cronScheduleBuilder).build(); + + // 放入参数,运行时的方法可以获取 + jobDetail.getJobDataMap().put(ScheduleConstants.TASK_PROPERTIES, job); + + // 判断是否存在 + if (scheduler.checkExists(getJobKey(jobId, jobGroup))) + { + // 防止创建时存在数据问题 先移除,然后在执行创建操作 + scheduler.deleteJob(getJobKey(jobId, jobGroup)); + } + + // 判断任务是否过期 + if (StringUtils.isNotNull(CronUtils.getNextExecution(job.getCronExpression()))) + { + // 执行调度任务 + scheduler.scheduleJob(jobDetail, trigger); + } + + // 暂停任务 + if (job.getStatus().equals(ScheduleConstants.Status.PAUSE.getValue())) + { + scheduler.pauseJob(ScheduleUtils.getJobKey(jobId, jobGroup)); + } + } + + /** + * 设置定时任务策略 + */ + public static CronScheduleBuilder handleCronScheduleMisfirePolicy(SysJob job, CronScheduleBuilder cb) + throws TaskException + { + switch (job.getMisfirePolicy()) + { + case ScheduleConstants.MISFIRE_DEFAULT: + return cb; + case ScheduleConstants.MISFIRE_IGNORE_MISFIRES: + return cb.withMisfireHandlingInstructionIgnoreMisfires(); + case ScheduleConstants.MISFIRE_FIRE_AND_PROCEED: + return cb.withMisfireHandlingInstructionFireAndProceed(); + case ScheduleConstants.MISFIRE_DO_NOTHING: + return cb.withMisfireHandlingInstructionDoNothing(); + default: + throw new TaskException("The task misfire policy '" + job.getMisfirePolicy() + + "' cannot be used in cron schedule tasks", Code.CONFIG_ERROR); + } + } + + /** + * 检查包名是否为白名单配置 + * + * @param invokeTarget 目标字符串 + * @return 结果 + */ + public static boolean whiteList(String invokeTarget) + { + String packageName = StringUtils.substringBefore(invokeTarget, "("); + int count = StringUtils.countMatches(packageName, "."); + if (count > 1) + { + return StringUtils.containsAnyIgnoreCase(invokeTarget, Constants.JOB_WHITELIST_STR); + } + Object obj = SpringUtils.getBean(StringUtils.split(invokeTarget, ".")[0]); + String beanPackageName = obj.getClass().getPackage().getName(); + return StringUtils.containsAnyIgnoreCase(beanPackageName, Constants.JOB_WHITELIST_STR) + && !StringUtils.containsAnyIgnoreCase(beanPackageName, Constants.JOB_ERROR_STR); + } +} diff --git a/zzyl-quartz/src/main/resources/mapper/quartz/SysJobLogMapper.xml b/zzyl-quartz/src/main/resources/mapper/quartz/SysJobLogMapper.xml new file mode 100644 index 0000000..04d477f --- /dev/null +++ b/zzyl-quartz/src/main/resources/mapper/quartz/SysJobLogMapper.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + select job_log_id, job_name, job_group, invoke_target, job_message, status, exception_info, create_time + from sys_job_log + + + + + + + + + + delete from sys_job_log where job_log_id = #{jobLogId} + + + + delete from sys_job_log where job_log_id in + + #{jobLogId} + + + + + truncate table sys_job_log + + + + insert into sys_job_log( + job_log_id, + job_name, + job_group, + invoke_target, + job_message, + status, + exception_info, + create_time + )values( + #{jobLogId}, + #{jobName}, + #{jobGroup}, + #{invokeTarget}, + #{jobMessage}, + #{status}, + #{exceptionInfo}, + sysdate() + ) + + + \ No newline at end of file diff --git a/zzyl-quartz/src/main/resources/mapper/quartz/SysJobMapper.xml b/zzyl-quartz/src/main/resources/mapper/quartz/SysJobMapper.xml new file mode 100644 index 0000000..f9408df --- /dev/null +++ b/zzyl-quartz/src/main/resources/mapper/quartz/SysJobMapper.xml @@ -0,0 +1,111 @@ + + + + + + + + + + + + + + + + + + + + + + select job_id, job_name, job_group, invoke_target, cron_expression, misfire_policy, concurrent, status, create_by, create_time, remark + from sys_job + + + + + + + + + + delete from sys_job where job_id = #{jobId} + + + + delete from sys_job where job_id in + + #{jobId} + + + + + update sys_job + + job_name = #{jobName}, + job_group = #{jobGroup}, + invoke_target = #{invokeTarget}, + cron_expression = #{cronExpression}, + misfire_policy = #{misfirePolicy}, + concurrent = #{concurrent}, + status = #{status}, + remark = #{remark}, + update_by = #{updateBy}, + update_time = sysdate() + + where job_id = #{jobId} + + + + insert into sys_job( + job_id, + job_name, + job_group, + invoke_target, + cron_expression, + misfire_policy, + concurrent, + status, + remark, + create_by, + create_time + )values( + #{jobId}, + #{jobName}, + #{jobGroup}, + #{invokeTarget}, + #{cronExpression}, + #{misfirePolicy}, + #{concurrent}, + #{status}, + #{remark}, + #{createBy}, + sysdate() + ) + + + \ No newline at end of file diff --git a/zzyl-system/pom.xml b/zzyl-system/pom.xml new file mode 100644 index 0000000..8dd5698 --- /dev/null +++ b/zzyl-system/pom.xml @@ -0,0 +1,28 @@ + + + + zzyl + com.zzyl + 3.8.8 + + 4.0.0 + + zzyl-system + + + system系统模块 + + + + + + + com.zzyl + zzyl-common + + + + + \ No newline at end of file diff --git a/zzyl-system/src/main/java/com/zzyl/system/domain/SysCache.java b/zzyl-system/src/main/java/com/zzyl/system/domain/SysCache.java new file mode 100644 index 0000000..1122167 --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/domain/SysCache.java @@ -0,0 +1,81 @@ +package com.zzyl.system.domain; + +import com.zzyl.common.utils.StringUtils; + +/** + * 缓存信息 + * + * @author ruoyi + */ +public class SysCache +{ + /** 缓存名称 */ + private String cacheName = ""; + + /** 缓存键名 */ + private String cacheKey = ""; + + /** 缓存内容 */ + private String cacheValue = ""; + + /** 备注 */ + private String remark = ""; + + public SysCache() + { + + } + + public SysCache(String cacheName, String remark) + { + this.cacheName = cacheName; + this.remark = remark; + } + + public SysCache(String cacheName, String cacheKey, String cacheValue) + { + this.cacheName = StringUtils.replace(cacheName, ":", ""); + this.cacheKey = StringUtils.replace(cacheKey, cacheName, ""); + this.cacheValue = cacheValue; + } + + public String getCacheName() + { + return cacheName; + } + + public void setCacheName(String cacheName) + { + this.cacheName = cacheName; + } + + public String getCacheKey() + { + return cacheKey; + } + + public void setCacheKey(String cacheKey) + { + this.cacheKey = cacheKey; + } + + public String getCacheValue() + { + return cacheValue; + } + + public void setCacheValue(String cacheValue) + { + this.cacheValue = cacheValue; + } + + public String getRemark() + { + return remark; + } + + public void setRemark(String remark) + { + this.remark = remark; + } +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/domain/SysConfig.java b/zzyl-system/src/main/java/com/zzyl/system/domain/SysConfig.java new file mode 100644 index 0000000..4ca50c5 --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/domain/SysConfig.java @@ -0,0 +1,111 @@ +package com.zzyl.system.domain; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.zzyl.common.annotation.Excel; +import com.zzyl.common.annotation.Excel.ColumnType; +import com.zzyl.common.core.domain.BaseEntity; + +/** + * 参数配置表 sys_config + * + * @author ruoyi + */ +public class SysConfig extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 参数主键 */ + @Excel(name = "参数主键", cellType = ColumnType.NUMERIC) + private Long configId; + + /** 参数名称 */ + @Excel(name = "参数名称") + private String configName; + + /** 参数键名 */ + @Excel(name = "参数键名") + private String configKey; + + /** 参数键值 */ + @Excel(name = "参数键值") + private String configValue; + + /** 系统内置(Y是 N否) */ + @Excel(name = "系统内置", readConverterExp = "Y=是,N=否") + private String configType; + + public Long getConfigId() + { + return configId; + } + + public void setConfigId(Long configId) + { + this.configId = configId; + } + + @NotBlank(message = "参数名称不能为空") + @Size(min = 0, max = 100, message = "参数名称不能超过100个字符") + public String getConfigName() + { + return configName; + } + + public void setConfigName(String configName) + { + this.configName = configName; + } + + @NotBlank(message = "参数键名长度不能为空") + @Size(min = 0, max = 100, message = "参数键名长度不能超过100个字符") + public String getConfigKey() + { + return configKey; + } + + public void setConfigKey(String configKey) + { + this.configKey = configKey; + } + + @NotBlank(message = "参数键值不能为空") + @Size(min = 0, max = 500, message = "参数键值长度不能超过500个字符") + public String getConfigValue() + { + return configValue; + } + + public void setConfigValue(String configValue) + { + this.configValue = configValue; + } + + public String getConfigType() + { + return configType; + } + + public void setConfigType(String configType) + { + this.configType = configType; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("configId", getConfigId()) + .append("configName", getConfigName()) + .append("configKey", getConfigKey()) + .append("configValue", getConfigValue()) + .append("configType", getConfigType()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/domain/SysLogininfor.java b/zzyl-system/src/main/java/com/zzyl/system/domain/SysLogininfor.java new file mode 100644 index 0000000..67feefe --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/domain/SysLogininfor.java @@ -0,0 +1,144 @@ +package com.zzyl.system.domain; + +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.zzyl.common.annotation.Excel; +import com.zzyl.common.annotation.Excel.ColumnType; +import com.zzyl.common.core.domain.BaseEntity; + +/** + * 系统访问记录表 sys_logininfor + * + * @author ruoyi + */ +public class SysLogininfor extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** ID */ + @Excel(name = "序号", cellType = ColumnType.NUMERIC) + private Long infoId; + + /** 用户账号 */ + @Excel(name = "用户账号") + private String userName; + + /** 登录状态 0成功 1失败 */ + @Excel(name = "登录状态", readConverterExp = "0=成功,1=失败") + private String status; + + /** 登录IP地址 */ + @Excel(name = "登录地址") + private String ipaddr; + + /** 登录地点 */ + @Excel(name = "登录地点") + private String loginLocation; + + /** 浏览器类型 */ + @Excel(name = "浏览器") + private String browser; + + /** 操作系统 */ + @Excel(name = "操作系统") + private String os; + + /** 提示消息 */ + @Excel(name = "提示消息") + private String msg; + + /** 访问时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "访问时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date loginTime; + + public Long getInfoId() + { + return infoId; + } + + public void setInfoId(Long infoId) + { + this.infoId = infoId; + } + + public String getUserName() + { + return userName; + } + + public void setUserName(String userName) + { + this.userName = userName; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + public String getIpaddr() + { + return ipaddr; + } + + public void setIpaddr(String ipaddr) + { + this.ipaddr = ipaddr; + } + + public String getLoginLocation() + { + return loginLocation; + } + + public void setLoginLocation(String loginLocation) + { + this.loginLocation = loginLocation; + } + + public String getBrowser() + { + return browser; + } + + public void setBrowser(String browser) + { + this.browser = browser; + } + + public String getOs() + { + return os; + } + + public void setOs(String os) + { + this.os = os; + } + + public String getMsg() + { + return msg; + } + + public void setMsg(String msg) + { + this.msg = msg; + } + + public Date getLoginTime() + { + return loginTime; + } + + public void setLoginTime(Date loginTime) + { + this.loginTime = loginTime; + } +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/domain/SysNotice.java b/zzyl-system/src/main/java/com/zzyl/system/domain/SysNotice.java new file mode 100644 index 0000000..5744b2b --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/domain/SysNotice.java @@ -0,0 +1,102 @@ +package com.zzyl.system.domain; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.zzyl.common.core.domain.BaseEntity; +import com.zzyl.common.xss.Xss; + +/** + * 通知公告表 sys_notice + * + * @author ruoyi + */ +public class SysNotice extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 公告ID */ + private Long noticeId; + + /** 公告标题 */ + private String noticeTitle; + + /** 公告类型(1通知 2公告) */ + private String noticeType; + + /** 公告内容 */ + private String noticeContent; + + /** 公告状态(0正常 1关闭) */ + private String status; + + public Long getNoticeId() + { + return noticeId; + } + + public void setNoticeId(Long noticeId) + { + this.noticeId = noticeId; + } + + public void setNoticeTitle(String noticeTitle) + { + this.noticeTitle = noticeTitle; + } + + @Xss(message = "公告标题不能包含脚本字符") + @NotBlank(message = "公告标题不能为空") + @Size(min = 0, max = 50, message = "公告标题不能超过50个字符") + public String getNoticeTitle() + { + return noticeTitle; + } + + public void setNoticeType(String noticeType) + { + this.noticeType = noticeType; + } + + public String getNoticeType() + { + return noticeType; + } + + public void setNoticeContent(String noticeContent) + { + this.noticeContent = noticeContent; + } + + public String getNoticeContent() + { + return noticeContent; + } + + public void setStatus(String status) + { + this.status = status; + } + + public String getStatus() + { + return status; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("noticeId", getNoticeId()) + .append("noticeTitle", getNoticeTitle()) + .append("noticeType", getNoticeType()) + .append("noticeContent", getNoticeContent()) + .append("status", getStatus()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/domain/SysOperLog.java b/zzyl-system/src/main/java/com/zzyl/system/domain/SysOperLog.java new file mode 100644 index 0000000..b2636f0 --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/domain/SysOperLog.java @@ -0,0 +1,269 @@ +package com.zzyl.system.domain; + +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.zzyl.common.annotation.Excel; +import com.zzyl.common.annotation.Excel.ColumnType; +import com.zzyl.common.core.domain.BaseEntity; + +/** + * 操作日志记录表 oper_log + * + * @author ruoyi + */ +public class SysOperLog extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 日志主键 */ + @Excel(name = "操作序号", cellType = ColumnType.NUMERIC) + private Long operId; + + /** 操作模块 */ + @Excel(name = "操作模块") + private String title; + + /** 业务类型(0其它 1新增 2修改 3删除) */ + @Excel(name = "业务类型", readConverterExp = "0=其它,1=新增,2=修改,3=删除,4=授权,5=导出,6=导入,7=强退,8=生成代码,9=清空数据") + private Integer businessType; + + /** 业务类型数组 */ + private Integer[] businessTypes; + + /** 请求方法 */ + @Excel(name = "请求方法") + private String method; + + /** 请求方式 */ + @Excel(name = "请求方式") + private String requestMethod; + + /** 操作类别(0其它 1后台用户 2手机端用户) */ + @Excel(name = "操作类别", readConverterExp = "0=其它,1=后台用户,2=手机端用户") + private Integer operatorType; + + /** 操作人员 */ + @Excel(name = "操作人员") + private String operName; + + /** 部门名称 */ + @Excel(name = "部门名称") + private String deptName; + + /** 请求url */ + @Excel(name = "请求地址") + private String operUrl; + + /** 操作地址 */ + @Excel(name = "操作地址") + private String operIp; + + /** 操作地点 */ + @Excel(name = "操作地点") + private String operLocation; + + /** 请求参数 */ + @Excel(name = "请求参数") + private String operParam; + + /** 返回参数 */ + @Excel(name = "返回参数") + private String jsonResult; + + /** 操作状态(0正常 1异常) */ + @Excel(name = "状态", readConverterExp = "0=正常,1=异常") + private Integer status; + + /** 错误消息 */ + @Excel(name = "错误消息") + private String errorMsg; + + /** 操作时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "操作时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date operTime; + + /** 消耗时间 */ + @Excel(name = "消耗时间", suffix = "毫秒") + private Long costTime; + + public Long getOperId() + { + return operId; + } + + public void setOperId(Long operId) + { + this.operId = operId; + } + + public String getTitle() + { + return title; + } + + public void setTitle(String title) + { + this.title = title; + } + + public Integer getBusinessType() + { + return businessType; + } + + public void setBusinessType(Integer businessType) + { + this.businessType = businessType; + } + + public Integer[] getBusinessTypes() + { + return businessTypes; + } + + public void setBusinessTypes(Integer[] businessTypes) + { + this.businessTypes = businessTypes; + } + + public String getMethod() + { + return method; + } + + public void setMethod(String method) + { + this.method = method; + } + + public String getRequestMethod() + { + return requestMethod; + } + + public void setRequestMethod(String requestMethod) + { + this.requestMethod = requestMethod; + } + + public Integer getOperatorType() + { + return operatorType; + } + + public void setOperatorType(Integer operatorType) + { + this.operatorType = operatorType; + } + + public String getOperName() + { + return operName; + } + + public void setOperName(String operName) + { + this.operName = operName; + } + + public String getDeptName() + { + return deptName; + } + + public void setDeptName(String deptName) + { + this.deptName = deptName; + } + + public String getOperUrl() + { + return operUrl; + } + + public void setOperUrl(String operUrl) + { + this.operUrl = operUrl; + } + + public String getOperIp() + { + return operIp; + } + + public void setOperIp(String operIp) + { + this.operIp = operIp; + } + + public String getOperLocation() + { + return operLocation; + } + + public void setOperLocation(String operLocation) + { + this.operLocation = operLocation; + } + + public String getOperParam() + { + return operParam; + } + + public void setOperParam(String operParam) + { + this.operParam = operParam; + } + + public String getJsonResult() + { + return jsonResult; + } + + public void setJsonResult(String jsonResult) + { + this.jsonResult = jsonResult; + } + + public Integer getStatus() + { + return status; + } + + public void setStatus(Integer status) + { + this.status = status; + } + + public String getErrorMsg() + { + return errorMsg; + } + + public void setErrorMsg(String errorMsg) + { + this.errorMsg = errorMsg; + } + + public Date getOperTime() + { + return operTime; + } + + public void setOperTime(Date operTime) + { + this.operTime = operTime; + } + + public Long getCostTime() + { + return costTime; + } + + public void setCostTime(Long costTime) + { + this.costTime = costTime; + } +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/domain/SysPost.java b/zzyl-system/src/main/java/com/zzyl/system/domain/SysPost.java new file mode 100644 index 0000000..c8fb4db --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/domain/SysPost.java @@ -0,0 +1,124 @@ +package com.zzyl.system.domain; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.zzyl.common.annotation.Excel; +import com.zzyl.common.annotation.Excel.ColumnType; +import com.zzyl.common.core.domain.BaseEntity; + +/** + * 岗位表 sys_post + * + * @author ruoyi + */ +public class SysPost extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 岗位序号 */ + @Excel(name = "岗位序号", cellType = ColumnType.NUMERIC) + private Long postId; + + /** 岗位编码 */ + @Excel(name = "岗位编码") + private String postCode; + + /** 岗位名称 */ + @Excel(name = "岗位名称") + private String postName; + + /** 岗位排序 */ + @Excel(name = "岗位排序") + private Integer postSort; + + /** 状态(0正常 1停用) */ + @Excel(name = "状态", readConverterExp = "0=正常,1=停用") + private String status; + + /** 用户是否存在此岗位标识 默认不存在 */ + private boolean flag = false; + + public Long getPostId() + { + return postId; + } + + public void setPostId(Long postId) + { + this.postId = postId; + } + + @NotBlank(message = "岗位编码不能为空") + @Size(min = 0, max = 64, message = "岗位编码长度不能超过64个字符") + public String getPostCode() + { + return postCode; + } + + public void setPostCode(String postCode) + { + this.postCode = postCode; + } + + @NotBlank(message = "岗位名称不能为空") + @Size(min = 0, max = 50, message = "岗位名称长度不能超过50个字符") + public String getPostName() + { + return postName; + } + + public void setPostName(String postName) + { + this.postName = postName; + } + + @NotNull(message = "显示顺序不能为空") + public Integer getPostSort() + { + return postSort; + } + + public void setPostSort(Integer postSort) + { + this.postSort = postSort; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + public boolean isFlag() + { + return flag; + } + + public void setFlag(boolean flag) + { + this.flag = flag; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("postId", getPostId()) + .append("postCode", getPostCode()) + .append("postName", getPostName()) + .append("postSort", getPostSort()) + .append("status", getStatus()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/domain/SysRoleDept.java b/zzyl-system/src/main/java/com/zzyl/system/domain/SysRoleDept.java new file mode 100644 index 0000000..c1b3cf2 --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/domain/SysRoleDept.java @@ -0,0 +1,46 @@ +package com.zzyl.system.domain; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 角色和部门关联 sys_role_dept + * + * @author ruoyi + */ +public class SysRoleDept +{ + /** 角色ID */ + private Long roleId; + + /** 部门ID */ + private Long deptId; + + public Long getRoleId() + { + return roleId; + } + + public void setRoleId(Long roleId) + { + this.roleId = roleId; + } + + public Long getDeptId() + { + return deptId; + } + + public void setDeptId(Long deptId) + { + this.deptId = deptId; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("roleId", getRoleId()) + .append("deptId", getDeptId()) + .toString(); + } +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/domain/SysRoleMenu.java b/zzyl-system/src/main/java/com/zzyl/system/domain/SysRoleMenu.java new file mode 100644 index 0000000..e6a284a --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/domain/SysRoleMenu.java @@ -0,0 +1,46 @@ +package com.zzyl.system.domain; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 角色和菜单关联 sys_role_menu + * + * @author ruoyi + */ +public class SysRoleMenu +{ + /** 角色ID */ + private Long roleId; + + /** 菜单ID */ + private Long menuId; + + public Long getRoleId() + { + return roleId; + } + + public void setRoleId(Long roleId) + { + this.roleId = roleId; + } + + public Long getMenuId() + { + return menuId; + } + + public void setMenuId(Long menuId) + { + this.menuId = menuId; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("roleId", getRoleId()) + .append("menuId", getMenuId()) + .toString(); + } +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/domain/SysUserOnline.java b/zzyl-system/src/main/java/com/zzyl/system/domain/SysUserOnline.java new file mode 100644 index 0000000..adff315 --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/domain/SysUserOnline.java @@ -0,0 +1,113 @@ +package com.zzyl.system.domain; + +/** + * 当前在线会话 + * + * @author ruoyi + */ +public class SysUserOnline +{ + /** 会话编号 */ + private String tokenId; + + /** 部门名称 */ + private String deptName; + + /** 用户名称 */ + private String userName; + + /** 登录IP地址 */ + private String ipaddr; + + /** 登录地址 */ + private String loginLocation; + + /** 浏览器类型 */ + private String browser; + + /** 操作系统 */ + private String os; + + /** 登录时间 */ + private Long loginTime; + + public String getTokenId() + { + return tokenId; + } + + public void setTokenId(String tokenId) + { + this.tokenId = tokenId; + } + + public String getDeptName() + { + return deptName; + } + + public void setDeptName(String deptName) + { + this.deptName = deptName; + } + + public String getUserName() + { + return userName; + } + + public void setUserName(String userName) + { + this.userName = userName; + } + + public String getIpaddr() + { + return ipaddr; + } + + public void setIpaddr(String ipaddr) + { + this.ipaddr = ipaddr; + } + + public String getLoginLocation() + { + return loginLocation; + } + + public void setLoginLocation(String loginLocation) + { + this.loginLocation = loginLocation; + } + + public String getBrowser() + { + return browser; + } + + public void setBrowser(String browser) + { + this.browser = browser; + } + + public String getOs() + { + return os; + } + + public void setOs(String os) + { + this.os = os; + } + + public Long getLoginTime() + { + return loginTime; + } + + public void setLoginTime(Long loginTime) + { + this.loginTime = loginTime; + } +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/domain/SysUserPost.java b/zzyl-system/src/main/java/com/zzyl/system/domain/SysUserPost.java new file mode 100644 index 0000000..7540754 --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/domain/SysUserPost.java @@ -0,0 +1,46 @@ +package com.zzyl.system.domain; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 用户和岗位关联 sys_user_post + * + * @author ruoyi + */ +public class SysUserPost +{ + /** 用户ID */ + private Long userId; + + /** 岗位ID */ + private Long postId; + + public Long getUserId() + { + return userId; + } + + public void setUserId(Long userId) + { + this.userId = userId; + } + + public Long getPostId() + { + return postId; + } + + public void setPostId(Long postId) + { + this.postId = postId; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("userId", getUserId()) + .append("postId", getPostId()) + .toString(); + } +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/domain/SysUserRole.java b/zzyl-system/src/main/java/com/zzyl/system/domain/SysUserRole.java new file mode 100644 index 0000000..665aee9 --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/domain/SysUserRole.java @@ -0,0 +1,46 @@ +package com.zzyl.system.domain; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 用户和角色关联 sys_user_role + * + * @author ruoyi + */ +public class SysUserRole +{ + /** 用户ID */ + private Long userId; + + /** 角色ID */ + private Long roleId; + + public Long getUserId() + { + return userId; + } + + public void setUserId(Long userId) + { + this.userId = userId; + } + + public Long getRoleId() + { + return roleId; + } + + public void setRoleId(Long roleId) + { + this.roleId = roleId; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("userId", getUserId()) + .append("roleId", getRoleId()) + .toString(); + } +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/domain/vo/MetaVo.java b/zzyl-system/src/main/java/com/zzyl/system/domain/vo/MetaVo.java new file mode 100644 index 0000000..cf9b704 --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/domain/vo/MetaVo.java @@ -0,0 +1,106 @@ +package com.zzyl.system.domain.vo; + +import com.zzyl.common.utils.StringUtils; + +/** + * 路由显示信息 + * + * @author ruoyi + */ +public class MetaVo +{ + /** + * 设置该路由在侧边栏和面包屑中展示的名字 + */ + private String title; + + /** + * 设置该路由的图标,对应路径src/assets/icons/svg + */ + private String icon; + + /** + * 设置为true,则不会被 缓存 + */ + private boolean noCache; + + /** + * 内链地址(http(s)://开头) + */ + private String link; + + public MetaVo() + { + } + + public MetaVo(String title, String icon) + { + this.title = title; + this.icon = icon; + } + + public MetaVo(String title, String icon, boolean noCache) + { + this.title = title; + this.icon = icon; + this.noCache = noCache; + } + + public MetaVo(String title, String icon, String link) + { + this.title = title; + this.icon = icon; + this.link = link; + } + + public MetaVo(String title, String icon, boolean noCache, String link) + { + this.title = title; + this.icon = icon; + this.noCache = noCache; + if (StringUtils.ishttp(link)) + { + this.link = link; + } + } + + public boolean isNoCache() + { + return noCache; + } + + public void setNoCache(boolean noCache) + { + this.noCache = noCache; + } + + public String getTitle() + { + return title; + } + + public void setTitle(String title) + { + this.title = title; + } + + public String getIcon() + { + return icon; + } + + public void setIcon(String icon) + { + this.icon = icon; + } + + public String getLink() + { + return link; + } + + public void setLink(String link) + { + this.link = link; + } +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/domain/vo/RouterVo.java b/zzyl-system/src/main/java/com/zzyl/system/domain/vo/RouterVo.java new file mode 100644 index 0000000..cba5a24 --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/domain/vo/RouterVo.java @@ -0,0 +1,148 @@ +package com.zzyl.system.domain.vo; + +import com.fasterxml.jackson.annotation.JsonInclude; +import java.util.List; + +/** + * 路由配置信息 + * + * @author ruoyi + */ +@JsonInclude(JsonInclude.Include.NON_EMPTY) +public class RouterVo +{ + /** + * 路由名字 + */ + private String name; + + /** + * 路由地址 + */ + private String path; + + /** + * 是否隐藏路由,当设置 true 的时候该路由不会再侧边栏出现 + */ + private boolean hidden; + + /** + * 重定向地址,当设置 noRedirect 的时候该路由在面包屑导航中不可被点击 + */ + private String redirect; + + /** + * 组件地址 + */ + private String component; + + /** + * 路由参数:如 {"id": 1, "name": "ry"} + */ + private String query; + + /** + * 当你一个路由下面的 children 声明的路由大于1个时,自动会变成嵌套的模式--如组件页面 + */ + private Boolean alwaysShow; + + /** + * 其他元素 + */ + private MetaVo meta; + + /** + * 子路由 + */ + private List children; + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public String getPath() + { + return path; + } + + public void setPath(String path) + { + this.path = path; + } + + public boolean getHidden() + { + return hidden; + } + + public void setHidden(boolean hidden) + { + this.hidden = hidden; + } + + public String getRedirect() + { + return redirect; + } + + public void setRedirect(String redirect) + { + this.redirect = redirect; + } + + public String getComponent() + { + return component; + } + + public void setComponent(String component) + { + this.component = component; + } + + public String getQuery() + { + return query; + } + + public void setQuery(String query) + { + this.query = query; + } + + public Boolean getAlwaysShow() + { + return alwaysShow; + } + + public void setAlwaysShow(Boolean alwaysShow) + { + this.alwaysShow = alwaysShow; + } + + public MetaVo getMeta() + { + return meta; + } + + public void setMeta(MetaVo meta) + { + this.meta = meta; + } + + public List getChildren() + { + return children; + } + + public void setChildren(List children) + { + this.children = children; + } +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/mapper/SysConfigMapper.java b/zzyl-system/src/main/java/com/zzyl/system/mapper/SysConfigMapper.java new file mode 100644 index 0000000..a154d1b --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/mapper/SysConfigMapper.java @@ -0,0 +1,76 @@ +package com.zzyl.system.mapper; + +import java.util.List; +import com.zzyl.system.domain.SysConfig; + +/** + * 参数配置 数据层 + * + * @author ruoyi + */ +public interface SysConfigMapper +{ + /** + * 查询参数配置信息 + * + * @param config 参数配置信息 + * @return 参数配置信息 + */ + public SysConfig selectConfig(SysConfig config); + + /** + * 通过ID查询配置 + * + * @param configId 参数ID + * @return 参数配置信息 + */ + public SysConfig selectConfigById(Long configId); + + /** + * 查询参数配置列表 + * + * @param config 参数配置信息 + * @return 参数配置集合 + */ + public List selectConfigList(SysConfig config); + + /** + * 根据键名查询参数配置信息 + * + * @param configKey 参数键名 + * @return 参数配置信息 + */ + public SysConfig checkConfigKeyUnique(String configKey); + + /** + * 新增参数配置 + * + * @param config 参数配置信息 + * @return 结果 + */ + public int insertConfig(SysConfig config); + + /** + * 修改参数配置 + * + * @param config 参数配置信息 + * @return 结果 + */ + public int updateConfig(SysConfig config); + + /** + * 删除参数配置 + * + * @param configId 参数ID + * @return 结果 + */ + public int deleteConfigById(Long configId); + + /** + * 批量删除参数信息 + * + * @param configIds 需要删除的参数ID + * @return 结果 + */ + public int deleteConfigByIds(Long[] configIds); +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/mapper/SysDeptMapper.java b/zzyl-system/src/main/java/com/zzyl/system/mapper/SysDeptMapper.java new file mode 100644 index 0000000..b83bf0a --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/mapper/SysDeptMapper.java @@ -0,0 +1,118 @@ +package com.zzyl.system.mapper; + +import java.util.List; +import org.apache.ibatis.annotations.Param; +import com.zzyl.common.core.domain.entity.SysDept; + +/** + * 部门管理 数据层 + * + * @author ruoyi + */ +public interface SysDeptMapper +{ + /** + * 查询部门管理数据 + * + * @param dept 部门信息 + * @return 部门信息集合 + */ + public List selectDeptList(SysDept dept); + + /** + * 根据角色ID查询部门树信息 + * + * @param roleId 角色ID + * @param deptCheckStrictly 部门树选择项是否关联显示 + * @return 选中部门列表 + */ + public List selectDeptListByRoleId(@Param("roleId") Long roleId, @Param("deptCheckStrictly") boolean deptCheckStrictly); + + /** + * 根据部门ID查询信息 + * + * @param deptId 部门ID + * @return 部门信息 + */ + public SysDept selectDeptById(Long deptId); + + /** + * 根据ID查询所有子部门 + * + * @param deptId 部门ID + * @return 部门列表 + */ + public List selectChildrenDeptById(Long deptId); + + /** + * 根据ID查询所有子部门(正常状态) + * + * @param deptId 部门ID + * @return 子部门数 + */ + public int selectNormalChildrenDeptById(Long deptId); + + /** + * 是否存在子节点 + * + * @param deptId 部门ID + * @return 结果 + */ + public int hasChildByDeptId(Long deptId); + + /** + * 查询部门是否存在用户 + * + * @param deptId 部门ID + * @return 结果 + */ + public int checkDeptExistUser(Long deptId); + + /** + * 校验部门名称是否唯一 + * + * @param deptName 部门名称 + * @param parentId 父部门ID + * @return 结果 + */ + public SysDept checkDeptNameUnique(@Param("deptName") String deptName, @Param("parentId") Long parentId); + + /** + * 新增部门信息 + * + * @param dept 部门信息 + * @return 结果 + */ + public int insertDept(SysDept dept); + + /** + * 修改部门信息 + * + * @param dept 部门信息 + * @return 结果 + */ + public int updateDept(SysDept dept); + + /** + * 修改所在部门正常状态 + * + * @param deptIds 部门ID组 + */ + public void updateDeptStatusNormal(Long[] deptIds); + + /** + * 修改子元素关系 + * + * @param depts 子元素 + * @return 结果 + */ + public int updateDeptChildren(@Param("depts") List depts); + + /** + * 删除部门管理信息 + * + * @param deptId 部门ID + * @return 结果 + */ + public int deleteDeptById(Long deptId); +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/mapper/SysDictDataMapper.java b/zzyl-system/src/main/java/com/zzyl/system/mapper/SysDictDataMapper.java new file mode 100644 index 0000000..6fbb5aa --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/mapper/SysDictDataMapper.java @@ -0,0 +1,95 @@ +package com.zzyl.system.mapper; + +import java.util.List; +import org.apache.ibatis.annotations.Param; +import com.zzyl.common.core.domain.entity.SysDictData; + +/** + * 字典表 数据层 + * + * @author ruoyi + */ +public interface SysDictDataMapper +{ + /** + * 根据条件分页查询字典数据 + * + * @param dictData 字典数据信息 + * @return 字典数据集合信息 + */ + public List selectDictDataList(SysDictData dictData); + + /** + * 根据字典类型查询字典数据 + * + * @param dictType 字典类型 + * @return 字典数据集合信息 + */ + public List selectDictDataByType(String dictType); + + /** + * 根据字典类型和字典键值查询字典数据信息 + * + * @param dictType 字典类型 + * @param dictValue 字典键值 + * @return 字典标签 + */ + public String selectDictLabel(@Param("dictType") String dictType, @Param("dictValue") String dictValue); + + /** + * 根据字典数据ID查询信息 + * + * @param dictCode 字典数据ID + * @return 字典数据 + */ + public SysDictData selectDictDataById(Long dictCode); + + /** + * 查询字典数据 + * + * @param dictType 字典类型 + * @return 字典数据 + */ + public int countDictDataByType(String dictType); + + /** + * 通过字典ID删除字典数据信息 + * + * @param dictCode 字典数据ID + * @return 结果 + */ + public int deleteDictDataById(Long dictCode); + + /** + * 批量删除字典数据信息 + * + * @param dictCodes 需要删除的字典数据ID + * @return 结果 + */ + public int deleteDictDataByIds(Long[] dictCodes); + + /** + * 新增字典数据信息 + * + * @param dictData 字典数据信息 + * @return 结果 + */ + public int insertDictData(SysDictData dictData); + + /** + * 修改字典数据信息 + * + * @param dictData 字典数据信息 + * @return 结果 + */ + public int updateDictData(SysDictData dictData); + + /** + * 同步修改字典类型 + * + * @param oldDictType 旧字典类型 + * @param newDictType 新旧字典类型 + * @return 结果 + */ + public int updateDictDataType(@Param("oldDictType") String oldDictType, @Param("newDictType") String newDictType); +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/mapper/SysDictTypeMapper.java b/zzyl-system/src/main/java/com/zzyl/system/mapper/SysDictTypeMapper.java new file mode 100644 index 0000000..1622cd9 --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/mapper/SysDictTypeMapper.java @@ -0,0 +1,83 @@ +package com.zzyl.system.mapper; + +import java.util.List; +import com.zzyl.common.core.domain.entity.SysDictType; + +/** + * 字典表 数据层 + * + * @author ruoyi + */ +public interface SysDictTypeMapper +{ + /** + * 根据条件分页查询字典类型 + * + * @param dictType 字典类型信息 + * @return 字典类型集合信息 + */ + public List selectDictTypeList(SysDictType dictType); + + /** + * 根据所有字典类型 + * + * @return 字典类型集合信息 + */ + public List selectDictTypeAll(); + + /** + * 根据字典类型ID查询信息 + * + * @param dictId 字典类型ID + * @return 字典类型 + */ + public SysDictType selectDictTypeById(Long dictId); + + /** + * 根据字典类型查询信息 + * + * @param dictType 字典类型 + * @return 字典类型 + */ + public SysDictType selectDictTypeByType(String dictType); + + /** + * 通过字典ID删除字典信息 + * + * @param dictId 字典ID + * @return 结果 + */ + public int deleteDictTypeById(Long dictId); + + /** + * 批量删除字典类型信息 + * + * @param dictIds 需要删除的字典ID + * @return 结果 + */ + public int deleteDictTypeByIds(Long[] dictIds); + + /** + * 新增字典类型信息 + * + * @param dictType 字典类型信息 + * @return 结果 + */ + public int insertDictType(SysDictType dictType); + + /** + * 修改字典类型信息 + * + * @param dictType 字典类型信息 + * @return 结果 + */ + public int updateDictType(SysDictType dictType); + + /** + * 校验字典类型称是否唯一 + * + * @param dictType 字典类型 + * @return 结果 + */ + public SysDictType checkDictTypeUnique(String dictType); +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/mapper/SysLogininforMapper.java b/zzyl-system/src/main/java/com/zzyl/system/mapper/SysLogininforMapper.java new file mode 100644 index 0000000..21c31c6 --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/mapper/SysLogininforMapper.java @@ -0,0 +1,42 @@ +package com.zzyl.system.mapper; + +import java.util.List; +import com.zzyl.system.domain.SysLogininfor; + +/** + * 系统访问日志情况信息 数据层 + * + * @author ruoyi + */ +public interface SysLogininforMapper +{ + /** + * 新增系统登录日志 + * + * @param logininfor 访问日志对象 + */ + public void insertLogininfor(SysLogininfor logininfor); + + /** + * 查询系统登录日志集合 + * + * @param logininfor 访问日志对象 + * @return 登录记录集合 + */ + public List selectLogininforList(SysLogininfor logininfor); + + /** + * 批量删除系统登录日志 + * + * @param infoIds 需要删除的登录日志ID + * @return 结果 + */ + public int deleteLogininforByIds(Long[] infoIds); + + /** + * 清空系统登录日志 + * + * @return 结果 + */ + public int cleanLogininfor(); +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/mapper/SysMenuMapper.java b/zzyl-system/src/main/java/com/zzyl/system/mapper/SysMenuMapper.java new file mode 100644 index 0000000..802e319 --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/mapper/SysMenuMapper.java @@ -0,0 +1,125 @@ +package com.zzyl.system.mapper; + +import java.util.List; +import org.apache.ibatis.annotations.Param; +import com.zzyl.common.core.domain.entity.SysMenu; + +/** + * 菜单表 数据层 + * + * @author ruoyi + */ +public interface SysMenuMapper +{ + /** + * 查询系统菜单列表 + * + * @param menu 菜单信息 + * @return 菜单列表 + */ + public List selectMenuList(SysMenu menu); + + /** + * 根据用户所有权限 + * + * @return 权限列表 + */ + public List selectMenuPerms(); + + /** + * 根据用户查询系统菜单列表 + * + * @param menu 菜单信息 + * @return 菜单列表 + */ + public List selectMenuListByUserId(SysMenu menu); + + /** + * 根据角色ID查询权限 + * + * @param roleId 角色ID + * @return 权限列表 + */ + public List selectMenuPermsByRoleId(Long roleId); + + /** + * 根据用户ID查询权限 + * + * @param userId 用户ID + * @return 权限列表 + */ + public List selectMenuPermsByUserId(Long userId); + + /** + * 根据用户ID查询菜单 + * + * @return 菜单列表 + */ + public List selectMenuTreeAll(); + + /** + * 根据用户ID查询菜单 + * + * @param userId 用户ID + * @return 菜单列表 + */ + public List selectMenuTreeByUserId(Long userId); + + /** + * 根据角色ID查询菜单树信息 + * + * @param roleId 角色ID + * @param menuCheckStrictly 菜单树选择项是否关联显示 + * @return 选中菜单列表 + */ + public List selectMenuListByRoleId(@Param("roleId") Long roleId, @Param("menuCheckStrictly") boolean menuCheckStrictly); + + /** + * 根据菜单ID查询信息 + * + * @param menuId 菜单ID + * @return 菜单信息 + */ + public SysMenu selectMenuById(Long menuId); + + /** + * 是否存在菜单子节点 + * + * @param menuId 菜单ID + * @return 结果 + */ + public int hasChildByMenuId(Long menuId); + + /** + * 新增菜单信息 + * + * @param menu 菜单信息 + * @return 结果 + */ + public int insertMenu(SysMenu menu); + + /** + * 修改菜单信息 + * + * @param menu 菜单信息 + * @return 结果 + */ + public int updateMenu(SysMenu menu); + + /** + * 删除菜单管理信息 + * + * @param menuId 菜单ID + * @return 结果 + */ + public int deleteMenuById(Long menuId); + + /** + * 校验菜单名称是否唯一 + * + * @param menuName 菜单名称 + * @param parentId 父菜单ID + * @return 结果 + */ + public SysMenu checkMenuNameUnique(@Param("menuName") String menuName, @Param("parentId") Long parentId); +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/mapper/SysNoticeMapper.java b/zzyl-system/src/main/java/com/zzyl/system/mapper/SysNoticeMapper.java new file mode 100644 index 0000000..ba92df6 --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/mapper/SysNoticeMapper.java @@ -0,0 +1,60 @@ +package com.zzyl.system.mapper; + +import java.util.List; +import com.zzyl.system.domain.SysNotice; + +/** + * 通知公告表 数据层 + * + * @author ruoyi + */ +public interface SysNoticeMapper +{ + /** + * 查询公告信息 + * + * @param noticeId 公告ID + * @return 公告信息 + */ + public SysNotice selectNoticeById(Long noticeId); + + /** + * 查询公告列表 + * + * @param notice 公告信息 + * @return 公告集合 + */ + public List selectNoticeList(SysNotice notice); + + /** + * 新增公告 + * + * @param notice 公告信息 + * @return 结果 + */ + public int insertNotice(SysNotice notice); + + /** + * 修改公告 + * + * @param notice 公告信息 + * @return 结果 + */ + public int updateNotice(SysNotice notice); + + /** + * 批量删除公告 + * + * @param noticeId 公告ID + * @return 结果 + */ + public int deleteNoticeById(Long noticeId); + + /** + * 批量删除公告信息 + * + * @param noticeIds 需要删除的公告ID + * @return 结果 + */ + public int deleteNoticeByIds(Long[] noticeIds); +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/mapper/SysOperLogMapper.java b/zzyl-system/src/main/java/com/zzyl/system/mapper/SysOperLogMapper.java new file mode 100644 index 0000000..adda210 --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/mapper/SysOperLogMapper.java @@ -0,0 +1,48 @@ +package com.zzyl.system.mapper; + +import java.util.List; +import com.zzyl.system.domain.SysOperLog; + +/** + * 操作日志 数据层 + * + * @author ruoyi + */ +public interface SysOperLogMapper +{ + /** + * 新增操作日志 + * + * @param operLog 操作日志对象 + */ + public void insertOperlog(SysOperLog operLog); + + /** + * 查询系统操作日志集合 + * + * @param operLog 操作日志对象 + * @return 操作日志集合 + */ + public List selectOperLogList(SysOperLog operLog); + + /** + * 批量删除系统操作日志 + * + * @param operIds 需要删除的操作日志ID + * @return 结果 + */ + public int deleteOperLogByIds(Long[] operIds); + + /** + * 查询操作日志详细 + * + * @param operId 操作ID + * @return 操作日志对象 + */ + public SysOperLog selectOperLogById(Long operId); + + /** + * 清空操作日志 + */ + public void cleanOperLog(); +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/mapper/SysPostMapper.java b/zzyl-system/src/main/java/com/zzyl/system/mapper/SysPostMapper.java new file mode 100644 index 0000000..bcda841 --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/mapper/SysPostMapper.java @@ -0,0 +1,99 @@ +package com.zzyl.system.mapper; + +import java.util.List; +import com.zzyl.system.domain.SysPost; + +/** + * 岗位信息 数据层 + * + * @author ruoyi + */ +public interface SysPostMapper +{ + /** + * 查询岗位数据集合 + * + * @param post 岗位信息 + * @return 岗位数据集合 + */ + public List selectPostList(SysPost post); + + /** + * 查询所有岗位 + * + * @return 岗位列表 + */ + public List selectPostAll(); + + /** + * 通过岗位ID查询岗位信息 + * + * @param postId 岗位ID + * @return 角色对象信息 + */ + public SysPost selectPostById(Long postId); + + /** + * 根据用户ID获取岗位选择框列表 + * + * @param userId 用户ID + * @return 选中岗位ID列表 + */ + public List selectPostListByUserId(Long userId); + + /** + * 查询用户所属岗位组 + * + * @param userName 用户名 + * @return 结果 + */ + public List selectPostsByUserName(String userName); + + /** + * 删除岗位信息 + * + * @param postId 岗位ID + * @return 结果 + */ + public int deletePostById(Long postId); + + /** + * 批量删除岗位信息 + * + * @param postIds 需要删除的岗位ID + * @return 结果 + */ + public int deletePostByIds(Long[] postIds); + + /** + * 修改岗位信息 + * + * @param post 岗位信息 + * @return 结果 + */ + public int updatePost(SysPost post); + + /** + * 新增岗位信息 + * + * @param post 岗位信息 + * @return 结果 + */ + public int insertPost(SysPost post); + + /** + * 校验岗位名称 + * + * @param postName 岗位名称 + * @return 结果 + */ + public SysPost checkPostNameUnique(String postName); + + /** + * 校验岗位编码 + * + * @param postCode 岗位编码 + * @return 结果 + */ + public SysPost checkPostCodeUnique(String postCode); +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/mapper/SysRoleDeptMapper.java b/zzyl-system/src/main/java/com/zzyl/system/mapper/SysRoleDeptMapper.java new file mode 100644 index 0000000..ac7e663 --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/mapper/SysRoleDeptMapper.java @@ -0,0 +1,44 @@ +package com.zzyl.system.mapper; + +import java.util.List; +import com.zzyl.system.domain.SysRoleDept; + +/** + * 角色与部门关联表 数据层 + * + * @author ruoyi + */ +public interface SysRoleDeptMapper +{ + /** + * 通过角色ID删除角色和部门关联 + * + * @param roleId 角色ID + * @return 结果 + */ + public int deleteRoleDeptByRoleId(Long roleId); + + /** + * 批量删除角色部门关联信息 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteRoleDept(Long[] ids); + + /** + * 查询部门使用数量 + * + * @param deptId 部门ID + * @return 结果 + */ + public int selectCountRoleDeptByDeptId(Long deptId); + + /** + * 批量新增角色部门信息 + * + * @param roleDeptList 角色部门列表 + * @return 结果 + */ + public int batchRoleDept(List roleDeptList); +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/mapper/SysRoleMapper.java b/zzyl-system/src/main/java/com/zzyl/system/mapper/SysRoleMapper.java new file mode 100644 index 0000000..f9b6052 --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/mapper/SysRoleMapper.java @@ -0,0 +1,107 @@ +package com.zzyl.system.mapper; + +import java.util.List; +import com.zzyl.common.core.domain.entity.SysRole; + +/** + * 角色表 数据层 + * + * @author ruoyi + */ +public interface SysRoleMapper +{ + /** + * 根据条件分页查询角色数据 + * + * @param role 角色信息 + * @return 角色数据集合信息 + */ + public List selectRoleList(SysRole role); + + /** + * 根据用户ID查询角色 + * + * @param userId 用户ID + * @return 角色列表 + */ + public List selectRolePermissionByUserId(Long userId); + + /** + * 查询所有角色 + * + * @return 角色列表 + */ + public List selectRoleAll(); + + /** + * 根据用户ID获取角色选择框列表 + * + * @param userId 用户ID + * @return 选中角色ID列表 + */ + public List selectRoleListByUserId(Long userId); + + /** + * 通过角色ID查询角色 + * + * @param roleId 角色ID + * @return 角色对象信息 + */ + public SysRole selectRoleById(Long roleId); + + /** + * 根据用户ID查询角色 + * + * @param userName 用户名 + * @return 角色列表 + */ + public List selectRolesByUserName(String userName); + + /** + * 校验角色名称是否唯一 + * + * @param roleName 角色名称 + * @return 角色信息 + */ + public SysRole checkRoleNameUnique(String roleName); + + /** + * 校验角色权限是否唯一 + * + * @param roleKey 角色权限 + * @return 角色信息 + */ + public SysRole checkRoleKeyUnique(String roleKey); + + /** + * 修改角色信息 + * + * @param role 角色信息 + * @return 结果 + */ + public int updateRole(SysRole role); + + /** + * 新增角色信息 + * + * @param role 角色信息 + * @return 结果 + */ + public int insertRole(SysRole role); + + /** + * 通过角色ID删除角色 + * + * @param roleId 角色ID + * @return 结果 + */ + public int deleteRoleById(Long roleId); + + /** + * 批量删除角色信息 + * + * @param roleIds 需要删除的角色ID + * @return 结果 + */ + public int deleteRoleByIds(Long[] roleIds); +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/mapper/SysRoleMenuMapper.java b/zzyl-system/src/main/java/com/zzyl/system/mapper/SysRoleMenuMapper.java new file mode 100644 index 0000000..72e5bca --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/mapper/SysRoleMenuMapper.java @@ -0,0 +1,44 @@ +package com.zzyl.system.mapper; + +import java.util.List; +import com.zzyl.system.domain.SysRoleMenu; + +/** + * 角色与菜单关联表 数据层 + * + * @author ruoyi + */ +public interface SysRoleMenuMapper +{ + /** + * 查询菜单使用数量 + * + * @param menuId 菜单ID + * @return 结果 + */ + public int checkMenuExistRole(Long menuId); + + /** + * 通过角色ID删除角色和菜单关联 + * + * @param roleId 角色ID + * @return 结果 + */ + public int deleteRoleMenuByRoleId(Long roleId); + + /** + * 批量删除角色菜单关联信息 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteRoleMenu(Long[] ids); + + /** + * 批量新增角色菜单信息 + * + * @param roleMenuList 角色菜单列表 + * @return 结果 + */ + public int batchRoleMenu(List roleMenuList); +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/mapper/SysUserMapper.java b/zzyl-system/src/main/java/com/zzyl/system/mapper/SysUserMapper.java new file mode 100644 index 0000000..afc0df7 --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/mapper/SysUserMapper.java @@ -0,0 +1,131 @@ +package com.zzyl.system.mapper; + +import java.util.List; +import org.apache.ibatis.annotations.Param; +import com.zzyl.common.core.domain.entity.SysUser; +import org.apache.ibatis.annotations.Select; + +/** + * 用户表 数据层 + * + * @author ruoyi + */ +public interface SysUserMapper +{ + /** + * 根据条件分页查询用户列表 + * + * @param sysUser 用户信息 + * @return 用户信息集合信息 + */ + public List selectUserList(SysUser sysUser); + + /** + * 根据条件分页查询已配用户角色列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + public List selectAllocatedList(SysUser user); + + /** + * 根据条件分页查询未分配用户角色列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + public List selectUnallocatedList(SysUser user); + + /** + * 通过用户名查询用户 + * + * @param userName 用户名 + * @return 用户对象信息 + */ + public SysUser selectUserByUserName(String userName); + + /** + * 通过用户ID查询用户 + * + * @param userId 用户ID + * @return 用户对象信息 + */ + public SysUser selectUserById(Long userId); + + /** + * 新增用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + public int insertUser(SysUser user); + + /** + * 修改用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + public int updateUser(SysUser user); + + /** + * 修改用户头像 + * + * @param userName 用户名 + * @param avatar 头像地址 + * @return 结果 + */ + public int updateUserAvatar(@Param("userName") String userName, @Param("avatar") String avatar); + + /** + * 重置用户密码 + * + * @param userName 用户名 + * @param password 密码 + * @return 结果 + */ + public int resetUserPwd(@Param("userName") String userName, @Param("password") String password); + + /** + * 通过用户ID删除用户 + * + * @param userId 用户ID + * @return 结果 + */ + public int deleteUserById(Long userId); + + /** + * 批量删除用户信息 + * + * @param userIds 需要删除的用户ID + * @return 结果 + */ + public int deleteUserByIds(Long[] userIds); + + /** + * 校验用户名称是否唯一 + * + * @param userName 用户名称 + * @return 结果 + */ + public SysUser checkUserNameUnique(String userName); + + /** + * 校验手机号码是否唯一 + * + * @param phonenumber 手机号码 + * @return 结果 + */ + public SysUser checkPhoneUnique(String phonenumber); + + /** + * 校验email是否唯一 + * + * @param email 用户邮箱 + * @return 结果 + */ + public SysUser checkEmailUnique(String email); + + @Select("select * from sys_user where dept_id = #{deptId}") + List getUserListByDept(Long deptId); +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/mapper/SysUserPostMapper.java b/zzyl-system/src/main/java/com/zzyl/system/mapper/SysUserPostMapper.java new file mode 100644 index 0000000..ca5def1 --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/mapper/SysUserPostMapper.java @@ -0,0 +1,44 @@ +package com.zzyl.system.mapper; + +import java.util.List; +import com.zzyl.system.domain.SysUserPost; + +/** + * 用户与岗位关联表 数据层 + * + * @author ruoyi + */ +public interface SysUserPostMapper +{ + /** + * 通过用户ID删除用户和岗位关联 + * + * @param userId 用户ID + * @return 结果 + */ + public int deleteUserPostByUserId(Long userId); + + /** + * 通过岗位ID查询岗位使用数量 + * + * @param postId 岗位ID + * @return 结果 + */ + public int countUserPostById(Long postId); + + /** + * 批量删除用户和岗位关联 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteUserPost(Long[] ids); + + /** + * 批量新增用户岗位信息 + * + * @param userPostList 用户岗位列表 + * @return 结果 + */ + public int batchUserPost(List userPostList); +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/mapper/SysUserRoleMapper.java b/zzyl-system/src/main/java/com/zzyl/system/mapper/SysUserRoleMapper.java new file mode 100644 index 0000000..d7208e3 --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/mapper/SysUserRoleMapper.java @@ -0,0 +1,65 @@ +package com.zzyl.system.mapper; + +import java.util.List; +import org.apache.ibatis.annotations.Param; +import com.zzyl.system.domain.SysUserRole; + +/** + * 用户与角色关联表 数据层 + * + * @author ruoyi + */ +public interface SysUserRoleMapper +{ + /** + * 通过用户ID删除用户和角色关联 + * + * @param userId 用户ID + * @return 结果 + */ + public int deleteUserRoleByUserId(Long userId); + + /** + * 批量删除用户和角色关联 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteUserRole(Long[] ids); + + /** + * 通过角色ID查询角色使用数量 + * + * @param roleId 角色ID + * @return 结果 + */ + public int countUserRoleByRoleId(Long roleId); + + /** + * 批量新增用户角色信息 + * + * @param userRoleList 用户角色列表 + * @return 结果 + */ + public int batchUserRole(List userRoleList); + + /** + * 删除用户和角色关联信息 + * + * @param userRole 用户和角色关联信息 + * @return 结果 + */ + public int deleteUserRoleInfo(SysUserRole userRole); + + /** + * 批量取消授权用户角色 + * + * @param roleId 角色ID + * @param userIds 需要删除的用户数据ID + * @return 结果 + */ + public int deleteUserRoleInfos(@Param("roleId") Long roleId, @Param("userIds") Long[] userIds); + + List selectUserIdByRoleName(String roleName); + +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/service/ISysConfigService.java b/zzyl-system/src/main/java/com/zzyl/system/service/ISysConfigService.java new file mode 100644 index 0000000..92fa520 --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/service/ISysConfigService.java @@ -0,0 +1,89 @@ +package com.zzyl.system.service; + +import java.util.List; +import com.zzyl.system.domain.SysConfig; + +/** + * 参数配置 服务层 + * + * @author ruoyi + */ +public interface ISysConfigService +{ + /** + * 查询参数配置信息 + * + * @param configId 参数配置ID + * @return 参数配置信息 + */ + public SysConfig selectConfigById(Long configId); + + /** + * 根据键名查询参数配置信息 + * + * @param configKey 参数键名 + * @return 参数键值 + */ + public String selectConfigByKey(String configKey); + + /** + * 获取验证码开关 + * + * @return true开启,false关闭 + */ + public boolean selectCaptchaEnabled(); + + /** + * 查询参数配置列表 + * + * @param config 参数配置信息 + * @return 参数配置集合 + */ + public List selectConfigList(SysConfig config); + + /** + * 新增参数配置 + * + * @param config 参数配置信息 + * @return 结果 + */ + public int insertConfig(SysConfig config); + + /** + * 修改参数配置 + * + * @param config 参数配置信息 + * @return 结果 + */ + public int updateConfig(SysConfig config); + + /** + * 批量删除参数信息 + * + * @param configIds 需要删除的参数ID + */ + public void deleteConfigByIds(Long[] configIds); + + /** + * 加载参数缓存数据 + */ + public void loadingConfigCache(); + + /** + * 清空参数缓存数据 + */ + public void clearConfigCache(); + + /** + * 重置参数缓存数据 + */ + public void resetConfigCache(); + + /** + * 校验参数键名是否唯一 + * + * @param config 参数信息 + * @return 结果 + */ + public boolean checkConfigKeyUnique(SysConfig config); +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/service/ISysDeptService.java b/zzyl-system/src/main/java/com/zzyl/system/service/ISysDeptService.java new file mode 100644 index 0000000..faec6f5 --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/service/ISysDeptService.java @@ -0,0 +1,124 @@ +package com.zzyl.system.service; + +import java.util.List; +import com.zzyl.common.core.domain.TreeSelect; +import com.zzyl.common.core.domain.entity.SysDept; + +/** + * 部门管理 服务层 + * + * @author ruoyi + */ +public interface ISysDeptService +{ + /** + * 查询部门管理数据 + * + * @param dept 部门信息 + * @return 部门信息集合 + */ + public List selectDeptList(SysDept dept); + + /** + * 查询部门树结构信息 + * + * @param dept 部门信息 + * @return 部门树信息集合 + */ + public List selectDeptTreeList(SysDept dept); + + /** + * 构建前端所需要树结构 + * + * @param depts 部门列表 + * @return 树结构列表 + */ + public List buildDeptTree(List depts); + + /** + * 构建前端所需要下拉树结构 + * + * @param depts 部门列表 + * @return 下拉树结构列表 + */ + public List buildDeptTreeSelect(List depts); + + /** + * 根据角色ID查询部门树信息 + * + * @param roleId 角色ID + * @return 选中部门列表 + */ + public List selectDeptListByRoleId(Long roleId); + + /** + * 根据部门ID查询信息 + * + * @param deptId 部门ID + * @return 部门信息 + */ + public SysDept selectDeptById(Long deptId); + + /** + * 根据ID查询所有子部门(正常状态) + * + * @param deptId 部门ID + * @return 子部门数 + */ + public int selectNormalChildrenDeptById(Long deptId); + + /** + * 是否存在部门子节点 + * + * @param deptId 部门ID + * @return 结果 + */ + public boolean hasChildByDeptId(Long deptId); + + /** + * 查询部门是否存在用户 + * + * @param deptId 部门ID + * @return 结果 true 存在 false 不存在 + */ + public boolean checkDeptExistUser(Long deptId); + + /** + * 校验部门名称是否唯一 + * + * @param dept 部门信息 + * @return 结果 + */ + public boolean checkDeptNameUnique(SysDept dept); + + /** + * 校验部门是否有数据权限 + * + * @param deptId 部门id + */ + public void checkDeptDataScope(Long deptId); + + /** + * 新增保存部门信息 + * + * @param dept 部门信息 + * @return 结果 + */ + public int insertDept(SysDept dept); + + /** + * 修改保存部门信息 + * + * @param dept 部门信息 + * @return 结果 + */ + public int updateDept(SysDept dept); + + /** + * 删除部门管理信息 + * + * @param deptId 部门ID + * @return 结果 + */ + public int deleteDeptById(Long deptId); +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/service/ISysDictDataService.java b/zzyl-system/src/main/java/com/zzyl/system/service/ISysDictDataService.java new file mode 100644 index 0000000..89c3b5b --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/service/ISysDictDataService.java @@ -0,0 +1,60 @@ +package com.zzyl.system.service; + +import java.util.List; +import com.zzyl.common.core.domain.entity.SysDictData; + +/** + * 字典 业务层 + * + * @author ruoyi + */ +public interface ISysDictDataService +{ + /** + * 根据条件分页查询字典数据 + * + * @param dictData 字典数据信息 + * @return 字典数据集合信息 + */ + public List selectDictDataList(SysDictData dictData); + + /** + * 根据字典类型和字典键值查询字典数据信息 + * + * @param dictType 字典类型 + * @param dictValue 字典键值 + * @return 字典标签 + */ + public String selectDictLabel(String dictType, String dictValue); + + /** + * 根据字典数据ID查询信息 + * + * @param dictCode 字典数据ID + * @return 字典数据 + */ + public SysDictData selectDictDataById(Long dictCode); + + /** + * 批量删除字典数据信息 + * + * @param dictCodes 需要删除的字典数据ID + */ + public void deleteDictDataByIds(Long[] dictCodes); + + /** + * 新增保存字典数据信息 + * + * @param dictData 字典数据信息 + * @return 结果 + */ + public int insertDictData(SysDictData dictData); + + /** + * 修改保存字典数据信息 + * + * @param dictData 字典数据信息 + * @return 结果 + */ + public int updateDictData(SysDictData dictData); +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/service/ISysDictTypeService.java b/zzyl-system/src/main/java/com/zzyl/system/service/ISysDictTypeService.java new file mode 100644 index 0000000..5e7a815 --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/service/ISysDictTypeService.java @@ -0,0 +1,98 @@ +package com.zzyl.system.service; + +import java.util.List; +import com.zzyl.common.core.domain.entity.SysDictData; +import com.zzyl.common.core.domain.entity.SysDictType; + +/** + * 字典 业务层 + * + * @author ruoyi + */ +public interface ISysDictTypeService +{ + /** + * 根据条件分页查询字典类型 + * + * @param dictType 字典类型信息 + * @return 字典类型集合信息 + */ + public List selectDictTypeList(SysDictType dictType); + + /** + * 根据所有字典类型 + * + * @return 字典类型集合信息 + */ + public List selectDictTypeAll(); + + /** + * 根据字典类型查询字典数据 + * + * @param dictType 字典类型 + * @return 字典数据集合信息 + */ + public List selectDictDataByType(String dictType); + + /** + * 根据字典类型ID查询信息 + * + * @param dictId 字典类型ID + * @return 字典类型 + */ + public SysDictType selectDictTypeById(Long dictId); + + /** + * 根据字典类型查询信息 + * + * @param dictType 字典类型 + * @return 字典类型 + */ + public SysDictType selectDictTypeByType(String dictType); + + /** + * 批量删除字典信息 + * + * @param dictIds 需要删除的字典ID + */ + public void deleteDictTypeByIds(Long[] dictIds); + + /** + * 加载字典缓存数据 + */ + public void loadingDictCache(); + + /** + * 清空字典缓存数据 + */ + public void clearDictCache(); + + /** + * 重置字典缓存数据 + */ + public void resetDictCache(); + + /** + * 新增保存字典类型信息 + * + * @param dictType 字典类型信息 + * @return 结果 + */ + public int insertDictType(SysDictType dictType); + + /** + * 修改保存字典类型信息 + * + * @param dictType 字典类型信息 + * @return 结果 + */ + public int updateDictType(SysDictType dictType); + + /** + * 校验字典类型称是否唯一 + * + * @param dictType 字典类型 + * @return 结果 + */ + public boolean checkDictTypeUnique(SysDictType dictType); +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/service/ISysLogininforService.java b/zzyl-system/src/main/java/com/zzyl/system/service/ISysLogininforService.java new file mode 100644 index 0000000..2394eaf --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/service/ISysLogininforService.java @@ -0,0 +1,40 @@ +package com.zzyl.system.service; + +import java.util.List; +import com.zzyl.system.domain.SysLogininfor; + +/** + * 系统访问日志情况信息 服务层 + * + * @author ruoyi + */ +public interface ISysLogininforService +{ + /** + * 新增系统登录日志 + * + * @param logininfor 访问日志对象 + */ + public void insertLogininfor(SysLogininfor logininfor); + + /** + * 查询系统登录日志集合 + * + * @param logininfor 访问日志对象 + * @return 登录记录集合 + */ + public List selectLogininforList(SysLogininfor logininfor); + + /** + * 批量删除系统登录日志 + * + * @param infoIds 需要删除的登录日志ID + * @return 结果 + */ + public int deleteLogininforByIds(Long[] infoIds); + + /** + * 清空系统登录日志 + */ + public void cleanLogininfor(); +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/service/ISysMenuService.java b/zzyl-system/src/main/java/com/zzyl/system/service/ISysMenuService.java new file mode 100644 index 0000000..ddd0d8f --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/service/ISysMenuService.java @@ -0,0 +1,144 @@ +package com.zzyl.system.service; + +import java.util.List; +import java.util.Set; +import com.zzyl.common.core.domain.TreeSelect; +import com.zzyl.common.core.domain.entity.SysMenu; +import com.zzyl.system.domain.vo.RouterVo; + +/** + * 菜单 业务层 + * + * @author ruoyi + */ +public interface ISysMenuService +{ + /** + * 根据用户查询系统菜单列表 + * + * @param userId 用户ID + * @return 菜单列表 + */ + public List selectMenuList(Long userId); + + /** + * 根据用户查询系统菜单列表 + * + * @param menu 菜单信息 + * @param userId 用户ID + * @return 菜单列表 + */ + public List selectMenuList(SysMenu menu, Long userId); + + /** + * 根据用户ID查询权限 + * + * @param userId 用户ID + * @return 权限列表 + */ + public Set selectMenuPermsByUserId(Long userId); + + /** + * 根据角色ID查询权限 + * + * @param roleId 角色ID + * @return 权限列表 + */ + public Set selectMenuPermsByRoleId(Long roleId); + + /** + * 根据用户ID查询菜单树信息 + * + * @param userId 用户ID + * @return 菜单列表 + */ + public List selectMenuTreeByUserId(Long userId); + + /** + * 根据角色ID查询菜单树信息 + * + * @param roleId 角色ID + * @return 选中菜单列表 + */ + public List selectMenuListByRoleId(Long roleId); + + /** + * 构建前端路由所需要的菜单 + * + * @param menus 菜单列表 + * @return 路由列表 + */ + public List buildMenus(List menus); + + /** + * 构建前端所需要树结构 + * + * @param menus 菜单列表 + * @return 树结构列表 + */ + public List buildMenuTree(List menus); + + /** + * 构建前端所需要下拉树结构 + * + * @param menus 菜单列表 + * @return 下拉树结构列表 + */ + public List buildMenuTreeSelect(List menus); + + /** + * 根据菜单ID查询信息 + * + * @param menuId 菜单ID + * @return 菜单信息 + */ + public SysMenu selectMenuById(Long menuId); + + /** + * 是否存在菜单子节点 + * + * @param menuId 菜单ID + * @return 结果 true 存在 false 不存在 + */ + public boolean hasChildByMenuId(Long menuId); + + /** + * 查询菜单是否存在角色 + * + * @param menuId 菜单ID + * @return 结果 true 存在 false 不存在 + */ + public boolean checkMenuExistRole(Long menuId); + + /** + * 新增保存菜单信息 + * + * @param menu 菜单信息 + * @return 结果 + */ + public int insertMenu(SysMenu menu); + + /** + * 修改保存菜单信息 + * + * @param menu 菜单信息 + * @return 结果 + */ + public int updateMenu(SysMenu menu); + + /** + * 删除菜单管理信息 + * + * @param menuId 菜单ID + * @return 结果 + */ + public int deleteMenuById(Long menuId); + + /** + * 校验菜单名称是否唯一 + * + * @param menu 菜单信息 + * @return 结果 + */ + public boolean checkMenuNameUnique(SysMenu menu); +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/service/ISysNoticeService.java b/zzyl-system/src/main/java/com/zzyl/system/service/ISysNoticeService.java new file mode 100644 index 0000000..2d00225 --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/service/ISysNoticeService.java @@ -0,0 +1,60 @@ +package com.zzyl.system.service; + +import java.util.List; +import com.zzyl.system.domain.SysNotice; + +/** + * 公告 服务层 + * + * @author ruoyi + */ +public interface ISysNoticeService +{ + /** + * 查询公告信息 + * + * @param noticeId 公告ID + * @return 公告信息 + */ + public SysNotice selectNoticeById(Long noticeId); + + /** + * 查询公告列表 + * + * @param notice 公告信息 + * @return 公告集合 + */ + public List selectNoticeList(SysNotice notice); + + /** + * 新增公告 + * + * @param notice 公告信息 + * @return 结果 + */ + public int insertNotice(SysNotice notice); + + /** + * 修改公告 + * + * @param notice 公告信息 + * @return 结果 + */ + public int updateNotice(SysNotice notice); + + /** + * 删除公告信息 + * + * @param noticeId 公告ID + * @return 结果 + */ + public int deleteNoticeById(Long noticeId); + + /** + * 批量删除公告信息 + * + * @param noticeIds 需要删除的公告ID + * @return 结果 + */ + public int deleteNoticeByIds(Long[] noticeIds); +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/service/ISysOperLogService.java b/zzyl-system/src/main/java/com/zzyl/system/service/ISysOperLogService.java new file mode 100644 index 0000000..f2ae2bf --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/service/ISysOperLogService.java @@ -0,0 +1,48 @@ +package com.zzyl.system.service; + +import java.util.List; +import com.zzyl.system.domain.SysOperLog; + +/** + * 操作日志 服务层 + * + * @author ruoyi + */ +public interface ISysOperLogService +{ + /** + * 新增操作日志 + * + * @param operLog 操作日志对象 + */ + public void insertOperlog(SysOperLog operLog); + + /** + * 查询系统操作日志集合 + * + * @param operLog 操作日志对象 + * @return 操作日志集合 + */ + public List selectOperLogList(SysOperLog operLog); + + /** + * 批量删除系统操作日志 + * + * @param operIds 需要删除的操作日志ID + * @return 结果 + */ + public int deleteOperLogByIds(Long[] operIds); + + /** + * 查询操作日志详细 + * + * @param operId 操作ID + * @return 操作日志对象 + */ + public SysOperLog selectOperLogById(Long operId); + + /** + * 清空操作日志 + */ + public void cleanOperLog(); +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/service/ISysPostService.java b/zzyl-system/src/main/java/com/zzyl/system/service/ISysPostService.java new file mode 100644 index 0000000..11b9892 --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/service/ISysPostService.java @@ -0,0 +1,99 @@ +package com.zzyl.system.service; + +import java.util.List; +import com.zzyl.system.domain.SysPost; + +/** + * 岗位信息 服务层 + * + * @author ruoyi + */ +public interface ISysPostService +{ + /** + * 查询岗位信息集合 + * + * @param post 岗位信息 + * @return 岗位列表 + */ + public List selectPostList(SysPost post); + + /** + * 查询所有岗位 + * + * @return 岗位列表 + */ + public List selectPostAll(); + + /** + * 通过岗位ID查询岗位信息 + * + * @param postId 岗位ID + * @return 角色对象信息 + */ + public SysPost selectPostById(Long postId); + + /** + * 根据用户ID获取岗位选择框列表 + * + * @param userId 用户ID + * @return 选中岗位ID列表 + */ + public List selectPostListByUserId(Long userId); + + /** + * 校验岗位名称 + * + * @param post 岗位信息 + * @return 结果 + */ + public boolean checkPostNameUnique(SysPost post); + + /** + * 校验岗位编码 + * + * @param post 岗位信息 + * @return 结果 + */ + public boolean checkPostCodeUnique(SysPost post); + + /** + * 通过岗位ID查询岗位使用数量 + * + * @param postId 岗位ID + * @return 结果 + */ + public int countUserPostById(Long postId); + + /** + * 删除岗位信息 + * + * @param postId 岗位ID + * @return 结果 + */ + public int deletePostById(Long postId); + + /** + * 批量删除岗位信息 + * + * @param postIds 需要删除的岗位ID + * @return 结果 + */ + public int deletePostByIds(Long[] postIds); + + /** + * 新增保存岗位信息 + * + * @param post 岗位信息 + * @return 结果 + */ + public int insertPost(SysPost post); + + /** + * 修改保存岗位信息 + * + * @param post 岗位信息 + * @return 结果 + */ + public int updatePost(SysPost post); +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/service/ISysRoleService.java b/zzyl-system/src/main/java/com/zzyl/system/service/ISysRoleService.java new file mode 100644 index 0000000..1607a79 --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/service/ISysRoleService.java @@ -0,0 +1,173 @@ +package com.zzyl.system.service; + +import java.util.List; +import java.util.Set; +import com.zzyl.common.core.domain.entity.SysRole; +import com.zzyl.system.domain.SysUserRole; + +/** + * 角色业务层 + * + * @author ruoyi + */ +public interface ISysRoleService +{ + /** + * 根据条件分页查询角色数据 + * + * @param role 角色信息 + * @return 角色数据集合信息 + */ + public List selectRoleList(SysRole role); + + /** + * 根据用户ID查询角色列表 + * + * @param userId 用户ID + * @return 角色列表 + */ + public List selectRolesByUserId(Long userId); + + /** + * 根据用户ID查询角色权限 + * + * @param userId 用户ID + * @return 权限列表 + */ + public Set selectRolePermissionByUserId(Long userId); + + /** + * 查询所有角色 + * + * @return 角色列表 + */ + public List selectRoleAll(); + + /** + * 根据用户ID获取角色选择框列表 + * + * @param userId 用户ID + * @return 选中角色ID列表 + */ + public List selectRoleListByUserId(Long userId); + + /** + * 通过角色ID查询角色 + * + * @param roleId 角色ID + * @return 角色对象信息 + */ + public SysRole selectRoleById(Long roleId); + + /** + * 校验角色名称是否唯一 + * + * @param role 角色信息 + * @return 结果 + */ + public boolean checkRoleNameUnique(SysRole role); + + /** + * 校验角色权限是否唯一 + * + * @param role 角色信息 + * @return 结果 + */ + public boolean checkRoleKeyUnique(SysRole role); + + /** + * 校验角色是否允许操作 + * + * @param role 角色信息 + */ + public void checkRoleAllowed(SysRole role); + + /** + * 校验角色是否有数据权限 + * + * @param roleIds 角色id + */ + public void checkRoleDataScope(Long... roleIds); + + /** + * 通过角色ID查询角色使用数量 + * + * @param roleId 角色ID + * @return 结果 + */ + public int countUserRoleByRoleId(Long roleId); + + /** + * 新增保存角色信息 + * + * @param role 角色信息 + * @return 结果 + */ + public int insertRole(SysRole role); + + /** + * 修改保存角色信息 + * + * @param role 角色信息 + * @return 结果 + */ + public int updateRole(SysRole role); + + /** + * 修改角色状态 + * + * @param role 角色信息 + * @return 结果 + */ + public int updateRoleStatus(SysRole role); + + /** + * 修改数据权限信息 + * + * @param role 角色信息 + * @return 结果 + */ + public int authDataScope(SysRole role); + + /** + * 通过角色ID删除角色 + * + * @param roleId 角色ID + * @return 结果 + */ + public int deleteRoleById(Long roleId); + + /** + * 批量删除角色信息 + * + * @param roleIds 需要删除的角色ID + * @return 结果 + */ + public int deleteRoleByIds(Long[] roleIds); + + /** + * 取消授权用户角色 + * + * @param userRole 用户和角色关联信息 + * @return 结果 + */ + public int deleteAuthUser(SysUserRole userRole); + + /** + * 批量取消授权用户角色 + * + * @param roleId 角色ID + * @param userIds 需要取消授权的用户数据ID + * @return 结果 + */ + public int deleteAuthUsers(Long roleId, Long[] userIds); + + /** + * 批量选择授权用户角色 + * + * @param roleId 角色ID + * @param userIds 需要删除的用户数据ID + * @return 结果 + */ + public int insertAuthUsers(Long roleId, Long[] userIds); +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/service/ISysUserOnlineService.java b/zzyl-system/src/main/java/com/zzyl/system/service/ISysUserOnlineService.java new file mode 100644 index 0000000..8e4ab81 --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/service/ISysUserOnlineService.java @@ -0,0 +1,48 @@ +package com.zzyl.system.service; + +import com.zzyl.common.core.domain.model.LoginUser; +import com.zzyl.system.domain.SysUserOnline; + +/** + * 在线用户 服务层 + * + * @author ruoyi + */ +public interface ISysUserOnlineService +{ + /** + * 通过登录地址查询信息 + * + * @param ipaddr 登录地址 + * @param user 用户信息 + * @return 在线用户信息 + */ + public SysUserOnline selectOnlineByIpaddr(String ipaddr, LoginUser user); + + /** + * 通过用户名称查询信息 + * + * @param userName 用户名称 + * @param user 用户信息 + * @return 在线用户信息 + */ + public SysUserOnline selectOnlineByUserName(String userName, LoginUser user); + + /** + * 通过登录地址/用户名称查询信息 + * + * @param ipaddr 登录地址 + * @param userName 用户名称 + * @param user 用户信息 + * @return 在线用户信息 + */ + public SysUserOnline selectOnlineByInfo(String ipaddr, String userName, LoginUser user); + + /** + * 设置在线用户信息 + * + * @param user 用户信息 + * @return 在线用户 + */ + public SysUserOnline loginUserToUserOnline(LoginUser user); +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/service/ISysUserService.java b/zzyl-system/src/main/java/com/zzyl/system/service/ISysUserService.java new file mode 100644 index 0000000..f942598 --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/service/ISysUserService.java @@ -0,0 +1,212 @@ +package com.zzyl.system.service; + +import java.util.List; +import com.zzyl.common.core.domain.entity.SysUser; + +/** + * 用户 业务层 + * + * @author ruoyi + */ +public interface ISysUserService +{ + /** + * 根据条件分页查询用户列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + public List selectUserList(SysUser user); + + /** + * 根据条件分页查询已分配用户角色列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + public List selectAllocatedList(SysUser user); + + /** + * 根据条件分页查询未分配用户角色列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + public List selectUnallocatedList(SysUser user); + + /** + * 通过用户名查询用户 + * + * @param userName 用户名 + * @return 用户对象信息 + */ + public SysUser selectUserByUserName(String userName); + + /** + * 通过用户ID查询用户 + * + * @param userId 用户ID + * @return 用户对象信息 + */ + public SysUser selectUserById(Long userId); + + /** + * 根据用户ID查询用户所属角色组 + * + * @param userName 用户名 + * @return 结果 + */ + public String selectUserRoleGroup(String userName); + + /** + * 根据用户ID查询用户所属岗位组 + * + * @param userName 用户名 + * @return 结果 + */ + public String selectUserPostGroup(String userName); + + /** + * 校验用户名称是否唯一 + * + * @param user 用户信息 + * @return 结果 + */ + public boolean checkUserNameUnique(SysUser user); + + /** + * 校验手机号码是否唯一 + * + * @param user 用户信息 + * @return 结果 + */ + public boolean checkPhoneUnique(SysUser user); + + /** + * 校验email是否唯一 + * + * @param user 用户信息 + * @return 结果 + */ + public boolean checkEmailUnique(SysUser user); + + /** + * 校验用户是否允许操作 + * + * @param user 用户信息 + */ + public void checkUserAllowed(SysUser user); + + /** + * 校验用户是否有数据权限 + * + * @param userId 用户id + */ + public void checkUserDataScope(Long userId); + + /** + * 新增用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + public int insertUser(SysUser user); + + /** + * 注册用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + public boolean registerUser(SysUser user); + + /** + * 修改用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + public int updateUser(SysUser user); + + /** + * 用户授权角色 + * + * @param userId 用户ID + * @param roleIds 角色组 + */ + public void insertUserAuth(Long userId, Long[] roleIds); + + /** + * 修改用户状态 + * + * @param user 用户信息 + * @return 结果 + */ + public int updateUserStatus(SysUser user); + + /** + * 修改用户基本信息 + * + * @param user 用户信息 + * @return 结果 + */ + public int updateUserProfile(SysUser user); + + /** + * 修改用户头像 + * + * @param userName 用户名 + * @param avatar 头像地址 + * @return 结果 + */ + public boolean updateUserAvatar(String userName, String avatar); + + /** + * 重置用户密码 + * + * @param user 用户信息 + * @return 结果 + */ + public int resetPwd(SysUser user); + + /** + * 重置用户密码 + * + * @param userName 用户名 + * @param password 密码 + * @return 结果 + */ + public int resetUserPwd(String userName, String password); + + /** + * 通过用户ID删除用户 + * + * @param userId 用户ID + * @return 结果 + */ + public int deleteUserById(Long userId); + + /** + * 批量删除用户信息 + * + * @param userIds 需要删除的用户ID + * @return 结果 + */ + public int deleteUserByIds(Long[] userIds); + + /** + * 导入用户数据 + * + * @param userList 用户数据列表 + * @param isUpdateSupport 是否更新支持,如果已存在,则进行更新数据 + * @param operName 操作用户 + * @return 结果 + */ + public String importUser(List userList, Boolean isUpdateSupport, String operName); + + /** + * 根据部门编号查询员工列表 + * @return 结果 + */ + List getUserListByDept(Long deptId); +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/service/impl/SysConfigServiceImpl.java b/zzyl-system/src/main/java/com/zzyl/system/service/impl/SysConfigServiceImpl.java new file mode 100644 index 0000000..c2fb285 --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/service/impl/SysConfigServiceImpl.java @@ -0,0 +1,232 @@ +package com.zzyl.system.service.impl; + +import java.util.Collection; +import java.util.List; +import javax.annotation.PostConstruct; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.zzyl.common.annotation.DataSource; +import com.zzyl.common.constant.CacheConstants; +import com.zzyl.common.constant.UserConstants; +import com.zzyl.common.core.redis.RedisCache; +import com.zzyl.common.core.text.Convert; +import com.zzyl.common.enums.DataSourceType; +import com.zzyl.common.exception.ServiceException; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.system.domain.SysConfig; +import com.zzyl.system.mapper.SysConfigMapper; +import com.zzyl.system.service.ISysConfigService; + +/** + * 参数配置 服务层实现 + * + * @author ruoyi + */ +@Service +public class SysConfigServiceImpl implements ISysConfigService +{ + @Autowired + private SysConfigMapper configMapper; + + @Autowired + private RedisCache redisCache; + + /** + * 项目启动时,初始化参数到缓存 + */ + @PostConstruct + public void init() + { + loadingConfigCache(); + } + + /** + * 查询参数配置信息 + * + * @param configId 参数配置ID + * @return 参数配置信息 + */ + @Override + @DataSource(DataSourceType.MASTER) + public SysConfig selectConfigById(Long configId) + { + SysConfig config = new SysConfig(); + config.setConfigId(configId); + return configMapper.selectConfig(config); + } + + /** + * 根据键名查询参数配置信息 + * + * @param configKey 参数key + * @return 参数键值 + */ + @Override + public String selectConfigByKey(String configKey) + { + String configValue = Convert.toStr(redisCache.getCacheObject(getCacheKey(configKey))); + if (StringUtils.isNotEmpty(configValue)) + { + return configValue; + } + SysConfig config = new SysConfig(); + config.setConfigKey(configKey); + SysConfig retConfig = configMapper.selectConfig(config); + if (StringUtils.isNotNull(retConfig)) + { + redisCache.setCacheObject(getCacheKey(configKey), retConfig.getConfigValue()); + return retConfig.getConfigValue(); + } + return StringUtils.EMPTY; + } + + /** + * 获取验证码开关 + * + * @return true开启,false关闭 + */ + @Override + public boolean selectCaptchaEnabled() + { + String captchaEnabled = selectConfigByKey("sys.account.captchaEnabled"); + if (StringUtils.isEmpty(captchaEnabled)) + { + return true; + } + return Convert.toBool(captchaEnabled); + } + + /** + * 查询参数配置列表 + * + * @param config 参数配置信息 + * @return 参数配置集合 + */ + @Override + public List selectConfigList(SysConfig config) + { + return configMapper.selectConfigList(config); + } + + /** + * 新增参数配置 + * + * @param config 参数配置信息 + * @return 结果 + */ + @Override + public int insertConfig(SysConfig config) + { + int row = configMapper.insertConfig(config); + if (row > 0) + { + redisCache.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue()); + } + return row; + } + + /** + * 修改参数配置 + * + * @param config 参数配置信息 + * @return 结果 + */ + @Override + public int updateConfig(SysConfig config) + { + SysConfig temp = configMapper.selectConfigById(config.getConfigId()); + if (!StringUtils.equals(temp.getConfigKey(), config.getConfigKey())) + { + redisCache.deleteObject(getCacheKey(temp.getConfigKey())); + } + + int row = configMapper.updateConfig(config); + if (row > 0) + { + redisCache.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue()); + } + return row; + } + + /** + * 批量删除参数信息 + * + * @param configIds 需要删除的参数ID + */ + @Override + public void deleteConfigByIds(Long[] configIds) + { + for (Long configId : configIds) + { + SysConfig config = selectConfigById(configId); + if (StringUtils.equals(UserConstants.YES, config.getConfigType())) + { + throw new ServiceException(String.format("内置参数【%1$s】不能删除 ", config.getConfigKey())); + } + configMapper.deleteConfigById(configId); + redisCache.deleteObject(getCacheKey(config.getConfigKey())); + } + } + + /** + * 加载参数缓存数据 + */ + @Override + public void loadingConfigCache() + { + List configsList = configMapper.selectConfigList(new SysConfig()); + for (SysConfig config : configsList) + { + redisCache.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue()); + } + } + + /** + * 清空参数缓存数据 + */ + @Override + public void clearConfigCache() + { + Collection keys = redisCache.keys(CacheConstants.SYS_CONFIG_KEY + "*"); + redisCache.deleteObject(keys); + } + + /** + * 重置参数缓存数据 + */ + @Override + public void resetConfigCache() + { + clearConfigCache(); + loadingConfigCache(); + } + + /** + * 校验参数键名是否唯一 + * + * @param config 参数配置信息 + * @return 结果 + */ + @Override + public boolean checkConfigKeyUnique(SysConfig config) + { + Long configId = StringUtils.isNull(config.getConfigId()) ? -1L : config.getConfigId(); + SysConfig info = configMapper.checkConfigKeyUnique(config.getConfigKey()); + if (StringUtils.isNotNull(info) && info.getConfigId().longValue() != configId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 设置cache key + * + * @param configKey 参数键 + * @return 缓存键key + */ + private String getCacheKey(String configKey) + { + return CacheConstants.SYS_CONFIG_KEY + configKey; + } +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/service/impl/SysDeptServiceImpl.java b/zzyl-system/src/main/java/com/zzyl/system/service/impl/SysDeptServiceImpl.java new file mode 100644 index 0000000..3fcb87e --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/service/impl/SysDeptServiceImpl.java @@ -0,0 +1,338 @@ +package com.zzyl.system.service.impl; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.stream.Collectors; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.zzyl.common.annotation.DataScope; +import com.zzyl.common.constant.UserConstants; +import com.zzyl.common.core.domain.TreeSelect; +import com.zzyl.common.core.domain.entity.SysDept; +import com.zzyl.common.core.domain.entity.SysRole; +import com.zzyl.common.core.domain.entity.SysUser; +import com.zzyl.common.core.text.Convert; +import com.zzyl.common.exception.ServiceException; +import com.zzyl.common.utils.SecurityUtils; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.common.utils.spring.SpringUtils; +import com.zzyl.system.mapper.SysDeptMapper; +import com.zzyl.system.mapper.SysRoleMapper; +import com.zzyl.system.service.ISysDeptService; + +/** + * 部门管理 服务实现 + * + * @author ruoyi + */ +@Service +public class SysDeptServiceImpl implements ISysDeptService +{ + @Autowired + private SysDeptMapper deptMapper; + + @Autowired + private SysRoleMapper roleMapper; + + /** + * 查询部门管理数据 + * + * @param dept 部门信息 + * @return 部门信息集合 + */ + @Override + @DataScope(deptAlias = "d") + public List selectDeptList(SysDept dept) + { + return deptMapper.selectDeptList(dept); + } + + /** + * 查询部门树结构信息 + * + * @param dept 部门信息 + * @return 部门树信息集合 + */ + @Override + public List selectDeptTreeList(SysDept dept) + { + List depts = SpringUtils.getAopProxy(this).selectDeptList(dept); + return buildDeptTreeSelect(depts); + } + + /** + * 构建前端所需要树结构 + * + * @param depts 部门列表 + * @return 树结构列表 + */ + @Override + public List buildDeptTree(List depts) + { + List returnList = new ArrayList(); + List tempList = depts.stream().map(SysDept::getDeptId).collect(Collectors.toList()); + for (SysDept dept : depts) + { + // 如果是顶级节点, 遍历该父节点的所有子节点 + if (!tempList.contains(dept.getParentId())) + { + recursionFn(depts, dept); + returnList.add(dept); + } + } + if (returnList.isEmpty()) + { + returnList = depts; + } + return returnList; + } + + /** + * 构建前端所需要下拉树结构 + * + * @param depts 部门列表 + * @return 下拉树结构列表 + */ + @Override + public List buildDeptTreeSelect(List depts) + { + List deptTrees = buildDeptTree(depts); + return deptTrees.stream().map(TreeSelect::new).collect(Collectors.toList()); + } + + /** + * 根据角色ID查询部门树信息 + * + * @param roleId 角色ID + * @return 选中部门列表 + */ + @Override + public List selectDeptListByRoleId(Long roleId) + { + SysRole role = roleMapper.selectRoleById(roleId); + return deptMapper.selectDeptListByRoleId(roleId, role.isDeptCheckStrictly()); + } + + /** + * 根据部门ID查询信息 + * + * @param deptId 部门ID + * @return 部门信息 + */ + @Override + public SysDept selectDeptById(Long deptId) + { + return deptMapper.selectDeptById(deptId); + } + + /** + * 根据ID查询所有子部门(正常状态) + * + * @param deptId 部门ID + * @return 子部门数 + */ + @Override + public int selectNormalChildrenDeptById(Long deptId) + { + return deptMapper.selectNormalChildrenDeptById(deptId); + } + + /** + * 是否存在子节点 + * + * @param deptId 部门ID + * @return 结果 + */ + @Override + public boolean hasChildByDeptId(Long deptId) + { + int result = deptMapper.hasChildByDeptId(deptId); + return result > 0; + } + + /** + * 查询部门是否存在用户 + * + * @param deptId 部门ID + * @return 结果 true 存在 false 不存在 + */ + @Override + public boolean checkDeptExistUser(Long deptId) + { + int result = deptMapper.checkDeptExistUser(deptId); + return result > 0; + } + + /** + * 校验部门名称是否唯一 + * + * @param dept 部门信息 + * @return 结果 + */ + @Override + public boolean checkDeptNameUnique(SysDept dept) + { + Long deptId = StringUtils.isNull(dept.getDeptId()) ? -1L : dept.getDeptId(); + SysDept info = deptMapper.checkDeptNameUnique(dept.getDeptName(), dept.getParentId()); + if (StringUtils.isNotNull(info) && info.getDeptId().longValue() != deptId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 校验部门是否有数据权限 + * + * @param deptId 部门id + */ + @Override + public void checkDeptDataScope(Long deptId) + { + if (!SysUser.isAdmin(SecurityUtils.getUserId()) && StringUtils.isNotNull(deptId)) + { + SysDept dept = new SysDept(); + dept.setDeptId(deptId); + List depts = SpringUtils.getAopProxy(this).selectDeptList(dept); + if (StringUtils.isEmpty(depts)) + { + throw new ServiceException("没有权限访问部门数据!"); + } + } + } + + /** + * 新增保存部门信息 + * + * @param dept 部门信息 + * @return 结果 + */ + @Override + public int insertDept(SysDept dept) + { + SysDept info = deptMapper.selectDeptById(dept.getParentId()); + // 如果父节点不为正常状态,则不允许新增子节点 + if (!UserConstants.DEPT_NORMAL.equals(info.getStatus())) + { + throw new ServiceException("部门停用,不允许新增"); + } + dept.setAncestors(info.getAncestors() + "," + dept.getParentId()); + return deptMapper.insertDept(dept); + } + + /** + * 修改保存部门信息 + * + * @param dept 部门信息 + * @return 结果 + */ + @Override + public int updateDept(SysDept dept) + { + SysDept newParentDept = deptMapper.selectDeptById(dept.getParentId()); + SysDept oldDept = deptMapper.selectDeptById(dept.getDeptId()); + if (StringUtils.isNotNull(newParentDept) && StringUtils.isNotNull(oldDept)) + { + String newAncestors = newParentDept.getAncestors() + "," + newParentDept.getDeptId(); + String oldAncestors = oldDept.getAncestors(); + dept.setAncestors(newAncestors); + updateDeptChildren(dept.getDeptId(), newAncestors, oldAncestors); + } + int result = deptMapper.updateDept(dept); + if (UserConstants.DEPT_NORMAL.equals(dept.getStatus()) && StringUtils.isNotEmpty(dept.getAncestors()) + && !StringUtils.equals("0", dept.getAncestors())) + { + // 如果该部门是启用状态,则启用该部门的所有上级部门 + updateParentDeptStatusNormal(dept); + } + return result; + } + + /** + * 修改该部门的父级部门状态 + * + * @param dept 当前部门 + */ + private void updateParentDeptStatusNormal(SysDept dept) + { + String ancestors = dept.getAncestors(); + Long[] deptIds = Convert.toLongArray(ancestors); + deptMapper.updateDeptStatusNormal(deptIds); + } + + /** + * 修改子元素关系 + * + * @param deptId 被修改的部门ID + * @param newAncestors 新的父ID集合 + * @param oldAncestors 旧的父ID集合 + */ + public void updateDeptChildren(Long deptId, String newAncestors, String oldAncestors) + { + List children = deptMapper.selectChildrenDeptById(deptId); + for (SysDept child : children) + { + child.setAncestors(child.getAncestors().replaceFirst(oldAncestors, newAncestors)); + } + if (children.size() > 0) + { + deptMapper.updateDeptChildren(children); + } + } + + /** + * 删除部门管理信息 + * + * @param deptId 部门ID + * @return 结果 + */ + @Override + public int deleteDeptById(Long deptId) + { + return deptMapper.deleteDeptById(deptId); + } + + /** + * 递归列表 + */ + private void recursionFn(List list, SysDept t) + { + // 得到子节点列表 + List childList = getChildList(list, t); + t.setChildren(childList); + for (SysDept tChild : childList) + { + if (hasChild(list, tChild)) + { + recursionFn(list, tChild); + } + } + } + + /** + * 得到子节点列表 + */ + private List getChildList(List list, SysDept t) + { + List tlist = new ArrayList(); + Iterator it = list.iterator(); + while (it.hasNext()) + { + SysDept n = (SysDept) it.next(); + if (StringUtils.isNotNull(n.getParentId()) && n.getParentId().longValue() == t.getDeptId().longValue()) + { + tlist.add(n); + } + } + return tlist; + } + + /** + * 判断是否有子节点 + */ + private boolean hasChild(List list, SysDept t) + { + return getChildList(list, t).size() > 0; + } +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/service/impl/SysDictDataServiceImpl.java b/zzyl-system/src/main/java/com/zzyl/system/service/impl/SysDictDataServiceImpl.java new file mode 100644 index 0000000..05f57e9 --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/service/impl/SysDictDataServiceImpl.java @@ -0,0 +1,111 @@ +package com.zzyl.system.service.impl; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.zzyl.common.core.domain.entity.SysDictData; +import com.zzyl.common.utils.DictUtils; +import com.zzyl.system.mapper.SysDictDataMapper; +import com.zzyl.system.service.ISysDictDataService; + +/** + * 字典 业务层处理 + * + * @author ruoyi + */ +@Service +public class SysDictDataServiceImpl implements ISysDictDataService +{ + @Autowired + private SysDictDataMapper dictDataMapper; + + /** + * 根据条件分页查询字典数据 + * + * @param dictData 字典数据信息 + * @return 字典数据集合信息 + */ + @Override + public List selectDictDataList(SysDictData dictData) + { + return dictDataMapper.selectDictDataList(dictData); + } + + /** + * 根据字典类型和字典键值查询字典数据信息 + * + * @param dictType 字典类型 + * @param dictValue 字典键值 + * @return 字典标签 + */ + @Override + public String selectDictLabel(String dictType, String dictValue) + { + return dictDataMapper.selectDictLabel(dictType, dictValue); + } + + /** + * 根据字典数据ID查询信息 + * + * @param dictCode 字典数据ID + * @return 字典数据 + */ + @Override + public SysDictData selectDictDataById(Long dictCode) + { + return dictDataMapper.selectDictDataById(dictCode); + } + + /** + * 批量删除字典数据信息 + * + * @param dictCodes 需要删除的字典数据ID + */ + @Override + public void deleteDictDataByIds(Long[] dictCodes) + { + for (Long dictCode : dictCodes) + { + SysDictData data = selectDictDataById(dictCode); + dictDataMapper.deleteDictDataById(dictCode); + List dictDatas = dictDataMapper.selectDictDataByType(data.getDictType()); + DictUtils.setDictCache(data.getDictType(), dictDatas); + } + } + + /** + * 新增保存字典数据信息 + * + * @param data 字典数据信息 + * @return 结果 + */ + @Override + public int insertDictData(SysDictData data) + { + int row = dictDataMapper.insertDictData(data); + if (row > 0) + { + List dictDatas = dictDataMapper.selectDictDataByType(data.getDictType()); + DictUtils.setDictCache(data.getDictType(), dictDatas); + } + return row; + } + + /** + * 修改保存字典数据信息 + * + * @param data 字典数据信息 + * @return 结果 + */ + @Override + public int updateDictData(SysDictData data) + { + int row = dictDataMapper.updateDictData(data); + if (row > 0) + { + List dictDatas = dictDataMapper.selectDictDataByType(data.getDictType()); + DictUtils.setDictCache(data.getDictType(), dictDatas); + } + return row; + } +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/service/impl/SysDictTypeServiceImpl.java b/zzyl-system/src/main/java/com/zzyl/system/service/impl/SysDictTypeServiceImpl.java new file mode 100644 index 0000000..2f533c2 --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/service/impl/SysDictTypeServiceImpl.java @@ -0,0 +1,223 @@ +package com.zzyl.system.service.impl; + +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import javax.annotation.PostConstruct; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import com.zzyl.common.constant.UserConstants; +import com.zzyl.common.core.domain.entity.SysDictData; +import com.zzyl.common.core.domain.entity.SysDictType; +import com.zzyl.common.exception.ServiceException; +import com.zzyl.common.utils.DictUtils; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.system.mapper.SysDictDataMapper; +import com.zzyl.system.mapper.SysDictTypeMapper; +import com.zzyl.system.service.ISysDictTypeService; + +/** + * 字典 业务层处理 + * + * @author ruoyi + */ +@Service +public class SysDictTypeServiceImpl implements ISysDictTypeService +{ + @Autowired + private SysDictTypeMapper dictTypeMapper; + + @Autowired + private SysDictDataMapper dictDataMapper; + + /** + * 项目启动时,初始化字典到缓存 + */ + @PostConstruct + public void init() + { + loadingDictCache(); + } + + /** + * 根据条件分页查询字典类型 + * + * @param dictType 字典类型信息 + * @return 字典类型集合信息 + */ + @Override + public List selectDictTypeList(SysDictType dictType) + { + return dictTypeMapper.selectDictTypeList(dictType); + } + + /** + * 根据所有字典类型 + * + * @return 字典类型集合信息 + */ + @Override + public List selectDictTypeAll() + { + return dictTypeMapper.selectDictTypeAll(); + } + + /** + * 根据字典类型查询字典数据 + * + * @param dictType 字典类型 + * @return 字典数据集合信息 + */ + @Override + public List selectDictDataByType(String dictType) + { + List dictDatas = DictUtils.getDictCache(dictType); + if (StringUtils.isNotEmpty(dictDatas)) + { + return dictDatas; + } + dictDatas = dictDataMapper.selectDictDataByType(dictType); + if (StringUtils.isNotEmpty(dictDatas)) + { + DictUtils.setDictCache(dictType, dictDatas); + return dictDatas; + } + return null; + } + + /** + * 根据字典类型ID查询信息 + * + * @param dictId 字典类型ID + * @return 字典类型 + */ + @Override + public SysDictType selectDictTypeById(Long dictId) + { + return dictTypeMapper.selectDictTypeById(dictId); + } + + /** + * 根据字典类型查询信息 + * + * @param dictType 字典类型 + * @return 字典类型 + */ + @Override + public SysDictType selectDictTypeByType(String dictType) + { + return dictTypeMapper.selectDictTypeByType(dictType); + } + + /** + * 批量删除字典类型信息 + * + * @param dictIds 需要删除的字典ID + */ + @Override + public void deleteDictTypeByIds(Long[] dictIds) + { + for (Long dictId : dictIds) + { + SysDictType dictType = selectDictTypeById(dictId); + if (dictDataMapper.countDictDataByType(dictType.getDictType()) > 0) + { + throw new ServiceException(String.format("%1$s已分配,不能删除", dictType.getDictName())); + } + dictTypeMapper.deleteDictTypeById(dictId); + DictUtils.removeDictCache(dictType.getDictType()); + } + } + + /** + * 加载字典缓存数据 + */ + @Override + public void loadingDictCache() + { + SysDictData dictData = new SysDictData(); + dictData.setStatus("0"); + Map> dictDataMap = dictDataMapper.selectDictDataList(dictData).stream().collect(Collectors.groupingBy(SysDictData::getDictType)); + for (Map.Entry> entry : dictDataMap.entrySet()) + { + DictUtils.setDictCache(entry.getKey(), entry.getValue().stream().sorted(Comparator.comparing(SysDictData::getDictSort)).collect(Collectors.toList())); + } + } + + /** + * 清空字典缓存数据 + */ + @Override + public void clearDictCache() + { + DictUtils.clearDictCache(); + } + + /** + * 重置字典缓存数据 + */ + @Override + public void resetDictCache() + { + clearDictCache(); + loadingDictCache(); + } + + /** + * 新增保存字典类型信息 + * + * @param dict 字典类型信息 + * @return 结果 + */ + @Override + public int insertDictType(SysDictType dict) + { + int row = dictTypeMapper.insertDictType(dict); + if (row > 0) + { + DictUtils.setDictCache(dict.getDictType(), null); + } + return row; + } + + /** + * 修改保存字典类型信息 + * + * @param dict 字典类型信息 + * @return 结果 + */ + @Override + @Transactional + public int updateDictType(SysDictType dict) + { + SysDictType oldDict = dictTypeMapper.selectDictTypeById(dict.getDictId()); + dictDataMapper.updateDictDataType(oldDict.getDictType(), dict.getDictType()); + int row = dictTypeMapper.updateDictType(dict); + if (row > 0) + { + List dictDatas = dictDataMapper.selectDictDataByType(dict.getDictType()); + DictUtils.setDictCache(dict.getDictType(), dictDatas); + } + return row; + } + + /** + * 校验字典类型称是否唯一 + * + * @param dict 字典类型 + * @return 结果 + */ + @Override + public boolean checkDictTypeUnique(SysDictType dict) + { + Long dictId = StringUtils.isNull(dict.getDictId()) ? -1L : dict.getDictId(); + SysDictType dictType = dictTypeMapper.checkDictTypeUnique(dict.getDictType()); + if (StringUtils.isNotNull(dictType) && dictType.getDictId().longValue() != dictId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/service/impl/SysLogininforServiceImpl.java b/zzyl-system/src/main/java/com/zzyl/system/service/impl/SysLogininforServiceImpl.java new file mode 100644 index 0000000..1827b49 --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/service/impl/SysLogininforServiceImpl.java @@ -0,0 +1,65 @@ +package com.zzyl.system.service.impl; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.zzyl.system.domain.SysLogininfor; +import com.zzyl.system.mapper.SysLogininforMapper; +import com.zzyl.system.service.ISysLogininforService; + +/** + * 系统访问日志情况信息 服务层处理 + * + * @author ruoyi + */ +@Service +public class SysLogininforServiceImpl implements ISysLogininforService +{ + + @Autowired + private SysLogininforMapper logininforMapper; + + /** + * 新增系统登录日志 + * + * @param logininfor 访问日志对象 + */ + @Override + public void insertLogininfor(SysLogininfor logininfor) + { + logininforMapper.insertLogininfor(logininfor); + } + + /** + * 查询系统登录日志集合 + * + * @param logininfor 访问日志对象 + * @return 登录记录集合 + */ + @Override + public List selectLogininforList(SysLogininfor logininfor) + { + return logininforMapper.selectLogininforList(logininfor); + } + + /** + * 批量删除系统登录日志 + * + * @param infoIds 需要删除的登录日志ID + * @return 结果 + */ + @Override + public int deleteLogininforByIds(Long[] infoIds) + { + return logininforMapper.deleteLogininforByIds(infoIds); + } + + /** + * 清空系统登录日志 + */ + @Override + public void cleanLogininfor() + { + logininforMapper.cleanLogininfor(); + } +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/service/impl/SysMenuServiceImpl.java b/zzyl-system/src/main/java/com/zzyl/system/service/impl/SysMenuServiceImpl.java new file mode 100644 index 0000000..b321173 --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/service/impl/SysMenuServiceImpl.java @@ -0,0 +1,543 @@ +package com.zzyl.system.service.impl; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.zzyl.common.constant.Constants; +import com.zzyl.common.constant.UserConstants; +import com.zzyl.common.core.domain.TreeSelect; +import com.zzyl.common.core.domain.entity.SysMenu; +import com.zzyl.common.core.domain.entity.SysRole; +import com.zzyl.common.core.domain.entity.SysUser; +import com.zzyl.common.utils.SecurityUtils; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.system.domain.vo.MetaVo; +import com.zzyl.system.domain.vo.RouterVo; +import com.zzyl.system.mapper.SysMenuMapper; +import com.zzyl.system.mapper.SysRoleMapper; +import com.zzyl.system.mapper.SysRoleMenuMapper; +import com.zzyl.system.service.ISysMenuService; + +/** + * 菜单 业务层处理 + * + * @author ruoyi + */ +@Service +public class SysMenuServiceImpl implements ISysMenuService +{ + public static final String PREMISSION_STRING = "perms[\"{0}\"]"; + + @Autowired + private SysMenuMapper menuMapper; + + @Autowired + private SysRoleMapper roleMapper; + + @Autowired + private SysRoleMenuMapper roleMenuMapper; + + /** + * 根据用户查询系统菜单列表 + * + * @param userId 用户ID + * @return 菜单列表 + */ + @Override + public List selectMenuList(Long userId) + { + return selectMenuList(new SysMenu(), userId); + } + + /** + * 查询系统菜单列表 + * + * @param menu 菜单信息 + * @return 菜单列表 + */ + @Override + public List selectMenuList(SysMenu menu, Long userId) + { + List menuList = null; + // 管理员显示所有菜单信息 + if (SysUser.isAdmin(userId)) + { + menuList = menuMapper.selectMenuList(menu); + } + else + { + menu.getParams().put("userId", userId); + menuList = menuMapper.selectMenuListByUserId(menu); + } + return menuList; + } + + /** + * 根据用户ID查询权限 + * + * @param userId 用户ID + * @return 权限列表 + */ + @Override + public Set selectMenuPermsByUserId(Long userId) + { + List perms = menuMapper.selectMenuPermsByUserId(userId); + Set permsSet = new HashSet<>(); + for (String perm : perms) + { + if (StringUtils.isNotEmpty(perm)) + { + permsSet.addAll(Arrays.asList(perm.trim().split(","))); + } + } + return permsSet; + } + + /** + * 根据角色ID查询权限 + * + * @param roleId 角色ID + * @return 权限列表 + */ + @Override + public Set selectMenuPermsByRoleId(Long roleId) + { + List perms = menuMapper.selectMenuPermsByRoleId(roleId); + Set permsSet = new HashSet<>(); + for (String perm : perms) + { + if (StringUtils.isNotEmpty(perm)) + { + permsSet.addAll(Arrays.asList(perm.trim().split(","))); + } + } + return permsSet; + } + + /** + * 根据用户ID查询菜单 + * + * @param userId 用户名称 + * @return 菜单列表 + */ + @Override + public List selectMenuTreeByUserId(Long userId) + { + List menus = null; + if (SecurityUtils.isAdmin(userId)) + { + menus = menuMapper.selectMenuTreeAll(); + } + else + { + menus = menuMapper.selectMenuTreeByUserId(userId); + } + return getChildPerms(menus, 0); + } + + /** + * 根据角色ID查询菜单树信息 + * + * @param roleId 角色ID + * @return 选中菜单列表 + */ + @Override + public List selectMenuListByRoleId(Long roleId) + { + SysRole role = roleMapper.selectRoleById(roleId); + return menuMapper.selectMenuListByRoleId(roleId, role.isMenuCheckStrictly()); + } + + /** + * 构建前端路由所需要的菜单 + * + * @param menus 菜单列表 + * @return 路由列表 + */ + @Override + public List buildMenus(List menus) + { + List routers = new LinkedList(); + for (SysMenu menu : menus) + { + RouterVo router = new RouterVo(); + router.setHidden("1".equals(menu.getVisible())); + router.setName(getRouteName(menu)); + router.setPath(getRouterPath(menu)); + router.setComponent(getComponent(menu)); + router.setQuery(menu.getQuery()); + router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), StringUtils.equals("1", menu.getIsCache()), menu.getPath())); + List cMenus = menu.getChildren(); + if (StringUtils.isNotEmpty(cMenus) && UserConstants.TYPE_DIR.equals(menu.getMenuType())) + { + router.setAlwaysShow(true); + router.setRedirect("noRedirect"); + router.setChildren(buildMenus(cMenus)); + } + else if (isMenuFrame(menu)) + { + router.setMeta(null); + List childrenList = new ArrayList(); + RouterVo children = new RouterVo(); + children.setPath(menu.getPath()); + children.setComponent(menu.getComponent()); + children.setName(getRouteName(menu.getRouteName(), menu.getPath())); + children.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), StringUtils.equals("1", menu.getIsCache()), menu.getPath())); + children.setQuery(menu.getQuery()); + childrenList.add(children); + router.setChildren(childrenList); + } + else if (menu.getParentId().intValue() == 0 && isInnerLink(menu)) + { + router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon())); + router.setPath("/"); + List childrenList = new ArrayList(); + RouterVo children = new RouterVo(); + String routerPath = innerLinkReplaceEach(menu.getPath()); + children.setPath(routerPath); + children.setComponent(UserConstants.INNER_LINK); + children.setName(getRouteName(menu.getRouteName(), routerPath)); + children.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), menu.getPath())); + childrenList.add(children); + router.setChildren(childrenList); + } + routers.add(router); + } + return routers; + } + + /** + * 构建前端所需要树结构 + * + * @param menus 菜单列表 + * @return 树结构列表 + */ + @Override + public List buildMenuTree(List menus) + { + List returnList = new ArrayList(); + List tempList = menus.stream().map(SysMenu::getMenuId).collect(Collectors.toList()); + for (Iterator iterator = menus.iterator(); iterator.hasNext();) + { + SysMenu menu = (SysMenu) iterator.next(); + // 如果是顶级节点, 遍历该父节点的所有子节点 + if (!tempList.contains(menu.getParentId())) + { + recursionFn(menus, menu); + returnList.add(menu); + } + } + if (returnList.isEmpty()) + { + returnList = menus; + } + return returnList; + } + + /** + * 构建前端所需要下拉树结构 + * + * @param menus 菜单列表 + * @return 下拉树结构列表 + */ + @Override + public List buildMenuTreeSelect(List menus) + { + List menuTrees = buildMenuTree(menus); + return menuTrees.stream().map(TreeSelect::new).collect(Collectors.toList()); + } + + /** + * 根据菜单ID查询信息 + * + * @param menuId 菜单ID + * @return 菜单信息 + */ + @Override + public SysMenu selectMenuById(Long menuId) + { + return menuMapper.selectMenuById(menuId); + } + + /** + * 是否存在菜单子节点 + * + * @param menuId 菜单ID + * @return 结果 + */ + @Override + public boolean hasChildByMenuId(Long menuId) + { + int result = menuMapper.hasChildByMenuId(menuId); + return result > 0; + } + + /** + * 查询菜单使用数量 + * + * @param menuId 菜单ID + * @return 结果 + */ + @Override + public boolean checkMenuExistRole(Long menuId) + { + int result = roleMenuMapper.checkMenuExistRole(menuId); + return result > 0; + } + + /** + * 新增保存菜单信息 + * + * @param menu 菜单信息 + * @return 结果 + */ + @Override + public int insertMenu(SysMenu menu) + { + return menuMapper.insertMenu(menu); + } + + /** + * 修改保存菜单信息 + * + * @param menu 菜单信息 + * @return 结果 + */ + @Override + public int updateMenu(SysMenu menu) + { + return menuMapper.updateMenu(menu); + } + + /** + * 删除菜单管理信息 + * + * @param menuId 菜单ID + * @return 结果 + */ + @Override + public int deleteMenuById(Long menuId) + { + return menuMapper.deleteMenuById(menuId); + } + + /** + * 校验菜单名称是否唯一 + * + * @param menu 菜单信息 + * @return 结果 + */ + @Override + public boolean checkMenuNameUnique(SysMenu menu) + { + Long menuId = StringUtils.isNull(menu.getMenuId()) ? -1L : menu.getMenuId(); + SysMenu info = menuMapper.checkMenuNameUnique(menu.getMenuName(), menu.getParentId()); + if (StringUtils.isNotNull(info) && info.getMenuId().longValue() != menuId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 获取路由名称 + * + * @param menu 菜单信息 + * @return 路由名称 + */ + public String getRouteName(SysMenu menu) + { + // 非外链并且是一级目录(类型为目录) + if (isMenuFrame(menu)) + { + return StringUtils.EMPTY; + } + return getRouteName(menu.getRouteName(), menu.getPath()); + } + + /** + * 获取路由名称,如没有配置路由名称则取路由地址 + * + * @param routerName 路由名称 + * @param path 路由地址 + * @return 路由名称(驼峰格式) + */ + public String getRouteName(String name, String path) + { + String routerName = StringUtils.isNotEmpty(name) ? name : path; + return StringUtils.capitalize(routerName); + } + + /** + * 获取路由地址 + * + * @param menu 菜单信息 + * @return 路由地址 + */ + public String getRouterPath(SysMenu menu) + { + String routerPath = menu.getPath(); + // 内链打开外网方式 + if (menu.getParentId().intValue() != 0 && isInnerLink(menu)) + { + routerPath = innerLinkReplaceEach(routerPath); + } + // 非外链并且是一级目录(类型为目录) + if (0 == menu.getParentId().intValue() && UserConstants.TYPE_DIR.equals(menu.getMenuType()) + && UserConstants.NO_FRAME.equals(menu.getIsFrame())) + { + routerPath = "/" + menu.getPath(); + } + // 非外链并且是一级目录(类型为菜单) + else if (isMenuFrame(menu)) + { + routerPath = "/"; + } + return routerPath; + } + + /** + * 获取组件信息 + * + * @param menu 菜单信息 + * @return 组件信息 + */ + public String getComponent(SysMenu menu) + { + String component = UserConstants.LAYOUT; + if (StringUtils.isNotEmpty(menu.getComponent()) && !isMenuFrame(menu)) + { + component = menu.getComponent(); + } + else if (StringUtils.isEmpty(menu.getComponent()) && menu.getParentId().intValue() != 0 && isInnerLink(menu)) + { + component = UserConstants.INNER_LINK; + } + else if (StringUtils.isEmpty(menu.getComponent()) && isParentView(menu)) + { + component = UserConstants.PARENT_VIEW; + } + return component; + } + + /** + * 是否为菜单内部跳转 + * + * @param menu 菜单信息 + * @return 结果 + */ + public boolean isMenuFrame(SysMenu menu) + { + return menu.getParentId().intValue() == 0 && UserConstants.TYPE_MENU.equals(menu.getMenuType()) + && menu.getIsFrame().equals(UserConstants.NO_FRAME); + } + + /** + * 是否为内链组件 + * + * @param menu 菜单信息 + * @return 结果 + */ + public boolean isInnerLink(SysMenu menu) + { + return menu.getIsFrame().equals(UserConstants.NO_FRAME) && StringUtils.ishttp(menu.getPath()); + } + + /** + * 是否为parent_view组件 + * + * @param menu 菜单信息 + * @return 结果 + */ + public boolean isParentView(SysMenu menu) + { + return menu.getParentId().intValue() != 0 && UserConstants.TYPE_DIR.equals(menu.getMenuType()); + } + + /** + * 根据父节点的ID获取所有子节点 + * + * @param list 分类表 + * @param parentId 传入的父节点ID + * @return String + */ + public List getChildPerms(List list, int parentId) + { + List returnList = new ArrayList(); + for (Iterator iterator = list.iterator(); iterator.hasNext();) + { + SysMenu t = (SysMenu) iterator.next(); + // 一、根据传入的某个父节点ID,遍历该父节点的所有子节点 + if (t.getParentId() == parentId) + { + recursionFn(list, t); + returnList.add(t); + } + } + return returnList; + } + + /** + * 递归列表 + * + * @param list 分类表 + * @param t 子节点 + */ + private void recursionFn(List list, SysMenu t) + { + // 得到子节点列表 + List childList = getChildList(list, t); + t.setChildren(childList); + for (SysMenu tChild : childList) + { + if (hasChild(list, tChild)) + { + recursionFn(list, tChild); + } + } + } + + /** + * 得到子节点列表 + */ + private List getChildList(List list, SysMenu t) + { + List tlist = new ArrayList(); + Iterator it = list.iterator(); + while (it.hasNext()) + { + SysMenu n = (SysMenu) it.next(); + if (n.getParentId().longValue() == t.getMenuId().longValue()) + { + tlist.add(n); + } + } + return tlist; + } + + /** + * 判断是否有子节点 + */ + private boolean hasChild(List list, SysMenu t) + { + return getChildList(list, t).size() > 0; + } + + /** + * 内链域名特殊字符替换 + * + * @return 替换后的内链域名 + */ + public String innerLinkReplaceEach(String path) + { + return StringUtils.replaceEach(path, new String[] { Constants.HTTP, Constants.HTTPS, Constants.WWW, ".", ":" }, + new String[] { "", "", "", "/", "/" }); + } +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/service/impl/SysNoticeServiceImpl.java b/zzyl-system/src/main/java/com/zzyl/system/service/impl/SysNoticeServiceImpl.java new file mode 100644 index 0000000..25385b7 --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/service/impl/SysNoticeServiceImpl.java @@ -0,0 +1,92 @@ +package com.zzyl.system.service.impl; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.zzyl.system.domain.SysNotice; +import com.zzyl.system.mapper.SysNoticeMapper; +import com.zzyl.system.service.ISysNoticeService; + +/** + * 公告 服务层实现 + * + * @author ruoyi + */ +@Service +public class SysNoticeServiceImpl implements ISysNoticeService +{ + @Autowired + private SysNoticeMapper noticeMapper; + + /** + * 查询公告信息 + * + * @param noticeId 公告ID + * @return 公告信息 + */ + @Override + public SysNotice selectNoticeById(Long noticeId) + { + return noticeMapper.selectNoticeById(noticeId); + } + + /** + * 查询公告列表 + * + * @param notice 公告信息 + * @return 公告集合 + */ + @Override + public List selectNoticeList(SysNotice notice) + { + return noticeMapper.selectNoticeList(notice); + } + + /** + * 新增公告 + * + * @param notice 公告信息 + * @return 结果 + */ + @Override + public int insertNotice(SysNotice notice) + { + return noticeMapper.insertNotice(notice); + } + + /** + * 修改公告 + * + * @param notice 公告信息 + * @return 结果 + */ + @Override + public int updateNotice(SysNotice notice) + { + return noticeMapper.updateNotice(notice); + } + + /** + * 删除公告对象 + * + * @param noticeId 公告ID + * @return 结果 + */ + @Override + public int deleteNoticeById(Long noticeId) + { + return noticeMapper.deleteNoticeById(noticeId); + } + + /** + * 批量删除公告信息 + * + * @param noticeIds 需要删除的公告ID + * @return 结果 + */ + @Override + public int deleteNoticeByIds(Long[] noticeIds) + { + return noticeMapper.deleteNoticeByIds(noticeIds); + } +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/service/impl/SysOperLogServiceImpl.java b/zzyl-system/src/main/java/com/zzyl/system/service/impl/SysOperLogServiceImpl.java new file mode 100644 index 0000000..4426aa6 --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/service/impl/SysOperLogServiceImpl.java @@ -0,0 +1,76 @@ +package com.zzyl.system.service.impl; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.zzyl.system.domain.SysOperLog; +import com.zzyl.system.mapper.SysOperLogMapper; +import com.zzyl.system.service.ISysOperLogService; + +/** + * 操作日志 服务层处理 + * + * @author ruoyi + */ +@Service +public class SysOperLogServiceImpl implements ISysOperLogService +{ + @Autowired + private SysOperLogMapper operLogMapper; + + /** + * 新增操作日志 + * + * @param operLog 操作日志对象 + */ + @Override + public void insertOperlog(SysOperLog operLog) + { + operLogMapper.insertOperlog(operLog); + } + + /** + * 查询系统操作日志集合 + * + * @param operLog 操作日志对象 + * @return 操作日志集合 + */ + @Override + public List selectOperLogList(SysOperLog operLog) + { + return operLogMapper.selectOperLogList(operLog); + } + + /** + * 批量删除系统操作日志 + * + * @param operIds 需要删除的操作日志ID + * @return 结果 + */ + @Override + public int deleteOperLogByIds(Long[] operIds) + { + return operLogMapper.deleteOperLogByIds(operIds); + } + + /** + * 查询操作日志详细 + * + * @param operId 操作ID + * @return 操作日志对象 + */ + @Override + public SysOperLog selectOperLogById(Long operId) + { + return operLogMapper.selectOperLogById(operId); + } + + /** + * 清空操作日志 + */ + @Override + public void cleanOperLog() + { + operLogMapper.cleanOperLog(); + } +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/service/impl/SysPostServiceImpl.java b/zzyl-system/src/main/java/com/zzyl/system/service/impl/SysPostServiceImpl.java new file mode 100644 index 0000000..207458a --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/service/impl/SysPostServiceImpl.java @@ -0,0 +1,178 @@ +package com.zzyl.system.service.impl; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.zzyl.common.constant.UserConstants; +import com.zzyl.common.exception.ServiceException; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.system.domain.SysPost; +import com.zzyl.system.mapper.SysPostMapper; +import com.zzyl.system.mapper.SysUserPostMapper; +import com.zzyl.system.service.ISysPostService; + +/** + * 岗位信息 服务层处理 + * + * @author ruoyi + */ +@Service +public class SysPostServiceImpl implements ISysPostService +{ + @Autowired + private SysPostMapper postMapper; + + @Autowired + private SysUserPostMapper userPostMapper; + + /** + * 查询岗位信息集合 + * + * @param post 岗位信息 + * @return 岗位信息集合 + */ + @Override + public List selectPostList(SysPost post) + { + return postMapper.selectPostList(post); + } + + /** + * 查询所有岗位 + * + * @return 岗位列表 + */ + @Override + public List selectPostAll() + { + return postMapper.selectPostAll(); + } + + /** + * 通过岗位ID查询岗位信息 + * + * @param postId 岗位ID + * @return 角色对象信息 + */ + @Override + public SysPost selectPostById(Long postId) + { + return postMapper.selectPostById(postId); + } + + /** + * 根据用户ID获取岗位选择框列表 + * + * @param userId 用户ID + * @return 选中岗位ID列表 + */ + @Override + public List selectPostListByUserId(Long userId) + { + return postMapper.selectPostListByUserId(userId); + } + + /** + * 校验岗位名称是否唯一 + * + * @param post 岗位信息 + * @return 结果 + */ + @Override + public boolean checkPostNameUnique(SysPost post) + { + Long postId = StringUtils.isNull(post.getPostId()) ? -1L : post.getPostId(); + SysPost info = postMapper.checkPostNameUnique(post.getPostName()); + if (StringUtils.isNotNull(info) && info.getPostId().longValue() != postId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 校验岗位编码是否唯一 + * + * @param post 岗位信息 + * @return 结果 + */ + @Override + public boolean checkPostCodeUnique(SysPost post) + { + Long postId = StringUtils.isNull(post.getPostId()) ? -1L : post.getPostId(); + SysPost info = postMapper.checkPostCodeUnique(post.getPostCode()); + if (StringUtils.isNotNull(info) && info.getPostId().longValue() != postId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 通过岗位ID查询岗位使用数量 + * + * @param postId 岗位ID + * @return 结果 + */ + @Override + public int countUserPostById(Long postId) + { + return userPostMapper.countUserPostById(postId); + } + + /** + * 删除岗位信息 + * + * @param postId 岗位ID + * @return 结果 + */ + @Override + public int deletePostById(Long postId) + { + return postMapper.deletePostById(postId); + } + + /** + * 批量删除岗位信息 + * + * @param postIds 需要删除的岗位ID + * @return 结果 + */ + @Override + public int deletePostByIds(Long[] postIds) + { + for (Long postId : postIds) + { + SysPost post = selectPostById(postId); + if (countUserPostById(postId) > 0) + { + throw new ServiceException(String.format("%1$s已分配,不能删除", post.getPostName())); + } + } + return postMapper.deletePostByIds(postIds); + } + + /** + * 新增保存岗位信息 + * + * @param post 岗位信息 + * @return 结果 + */ + @Override + public int insertPost(SysPost post) + { + return postMapper.insertPost(post); + } + + /** + * 修改保存岗位信息 + * + * @param post 岗位信息 + * @return 结果 + */ + @Override + public int updatePost(SysPost post) + { + return postMapper.updatePost(post); + } +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/service/impl/SysRoleServiceImpl.java b/zzyl-system/src/main/java/com/zzyl/system/service/impl/SysRoleServiceImpl.java new file mode 100644 index 0000000..2419382 --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/service/impl/SysRoleServiceImpl.java @@ -0,0 +1,427 @@ +package com.zzyl.system.service.impl; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import com.zzyl.common.annotation.DataScope; +import com.zzyl.common.constant.UserConstants; +import com.zzyl.common.core.domain.entity.SysRole; +import com.zzyl.common.core.domain.entity.SysUser; +import com.zzyl.common.exception.ServiceException; +import com.zzyl.common.utils.SecurityUtils; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.common.utils.spring.SpringUtils; +import com.zzyl.system.domain.SysRoleDept; +import com.zzyl.system.domain.SysRoleMenu; +import com.zzyl.system.domain.SysUserRole; +import com.zzyl.system.mapper.SysRoleDeptMapper; +import com.zzyl.system.mapper.SysRoleMapper; +import com.zzyl.system.mapper.SysRoleMenuMapper; +import com.zzyl.system.mapper.SysUserRoleMapper; +import com.zzyl.system.service.ISysRoleService; + +/** + * 角色 业务层处理 + * + * @author ruoyi + */ +@Service +public class SysRoleServiceImpl implements ISysRoleService +{ + @Autowired + private SysRoleMapper roleMapper; + + @Autowired + private SysRoleMenuMapper roleMenuMapper; + + @Autowired + private SysUserRoleMapper userRoleMapper; + + @Autowired + private SysRoleDeptMapper roleDeptMapper; + + /** + * 根据条件分页查询角色数据 + * + * @param role 角色信息 + * @return 角色数据集合信息 + */ + @Override + @DataScope(deptAlias = "d") + public List selectRoleList(SysRole role) + { + return roleMapper.selectRoleList(role); + } + + /** + * 根据用户ID查询角色 + * + * @param userId 用户ID + * @return 角色列表 + */ + @Override + public List selectRolesByUserId(Long userId) + { + List userRoles = roleMapper.selectRolePermissionByUserId(userId); + List roles = selectRoleAll(); + for (SysRole role : roles) + { + for (SysRole userRole : userRoles) + { + if (role.getRoleId().longValue() == userRole.getRoleId().longValue()) + { + role.setFlag(true); + break; + } + } + } + return roles; + } + + /** + * 根据用户ID查询权限 + * + * @param userId 用户ID + * @return 权限列表 + */ + @Override + public Set selectRolePermissionByUserId(Long userId) + { + List perms = roleMapper.selectRolePermissionByUserId(userId); + Set permsSet = new HashSet<>(); + for (SysRole perm : perms) + { + if (StringUtils.isNotNull(perm)) + { + permsSet.addAll(Arrays.asList(perm.getRoleKey().trim().split(","))); + } + } + return permsSet; + } + + /** + * 查询所有角色 + * + * @return 角色列表 + */ + @Override + public List selectRoleAll() + { + return SpringUtils.getAopProxy(this).selectRoleList(new SysRole()); + } + + /** + * 根据用户ID获取角色选择框列表 + * + * @param userId 用户ID + * @return 选中角色ID列表 + */ + @Override + public List selectRoleListByUserId(Long userId) + { + return roleMapper.selectRoleListByUserId(userId); + } + + /** + * 通过角色ID查询角色 + * + * @param roleId 角色ID + * @return 角色对象信息 + */ + @Override + public SysRole selectRoleById(Long roleId) + { + return roleMapper.selectRoleById(roleId); + } + + /** + * 校验角色名称是否唯一 + * + * @param role 角色信息 + * @return 结果 + */ + @Override + public boolean checkRoleNameUnique(SysRole role) + { + Long roleId = StringUtils.isNull(role.getRoleId()) ? -1L : role.getRoleId(); + SysRole info = roleMapper.checkRoleNameUnique(role.getRoleName()); + if (StringUtils.isNotNull(info) && info.getRoleId().longValue() != roleId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 校验角色权限是否唯一 + * + * @param role 角色信息 + * @return 结果 + */ + @Override + public boolean checkRoleKeyUnique(SysRole role) + { + Long roleId = StringUtils.isNull(role.getRoleId()) ? -1L : role.getRoleId(); + SysRole info = roleMapper.checkRoleKeyUnique(role.getRoleKey()); + if (StringUtils.isNotNull(info) && info.getRoleId().longValue() != roleId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 校验角色是否允许操作 + * + * @param role 角色信息 + */ + @Override + public void checkRoleAllowed(SysRole role) + { + if (StringUtils.isNotNull(role.getRoleId()) && role.isAdmin()) + { + throw new ServiceException("不允许操作超级管理员角色"); + } + } + + /** + * 校验角色是否有数据权限 + * + * @param roleIds 角色id + */ + @Override + public void checkRoleDataScope(Long... roleIds) + { + if (!SysUser.isAdmin(SecurityUtils.getUserId())) + { + for (Long roleId : roleIds) + { + SysRole role = new SysRole(); + role.setRoleId(roleId); + List roles = SpringUtils.getAopProxy(this).selectRoleList(role); + if (StringUtils.isEmpty(roles)) + { + throw new ServiceException("没有权限访问角色数据!"); + } + } + } + } + + /** + * 通过角色ID查询角色使用数量 + * + * @param roleId 角色ID + * @return 结果 + */ + @Override + public int countUserRoleByRoleId(Long roleId) + { + return userRoleMapper.countUserRoleByRoleId(roleId); + } + + /** + * 新增保存角色信息 + * + * @param role 角色信息 + * @return 结果 + */ + @Override + @Transactional + public int insertRole(SysRole role) + { + // 新增角色信息 + roleMapper.insertRole(role); + return insertRoleMenu(role); + } + + /** + * 修改保存角色信息 + * + * @param role 角色信息 + * @return 结果 + */ + @Override + @Transactional + public int updateRole(SysRole role) + { + // 修改角色信息 + roleMapper.updateRole(role); + // 删除角色与菜单关联 + roleMenuMapper.deleteRoleMenuByRoleId(role.getRoleId()); + return insertRoleMenu(role); + } + + /** + * 修改角色状态 + * + * @param role 角色信息 + * @return 结果 + */ + @Override + public int updateRoleStatus(SysRole role) + { + return roleMapper.updateRole(role); + } + + /** + * 修改数据权限信息 + * + * @param role 角色信息 + * @return 结果 + */ + @Override + @Transactional + public int authDataScope(SysRole role) + { + // 修改角色信息 + roleMapper.updateRole(role); + // 删除角色与部门关联 + roleDeptMapper.deleteRoleDeptByRoleId(role.getRoleId()); + // 新增角色和部门信息(数据权限) + return insertRoleDept(role); + } + + /** + * 新增角色菜单信息 + * + * @param role 角色对象 + */ + public int insertRoleMenu(SysRole role) + { + int rows = 1; + // 新增用户与角色管理 + List list = new ArrayList(); + for (Long menuId : role.getMenuIds()) + { + SysRoleMenu rm = new SysRoleMenu(); + rm.setRoleId(role.getRoleId()); + rm.setMenuId(menuId); + list.add(rm); + } + if (list.size() > 0) + { + rows = roleMenuMapper.batchRoleMenu(list); + } + return rows; + } + + /** + * 新增角色部门信息(数据权限) + * + * @param role 角色对象 + */ + public int insertRoleDept(SysRole role) + { + int rows = 1; + // 新增角色与部门(数据权限)管理 + List list = new ArrayList(); + for (Long deptId : role.getDeptIds()) + { + SysRoleDept rd = new SysRoleDept(); + rd.setRoleId(role.getRoleId()); + rd.setDeptId(deptId); + list.add(rd); + } + if (list.size() > 0) + { + rows = roleDeptMapper.batchRoleDept(list); + } + return rows; + } + + /** + * 通过角色ID删除角色 + * + * @param roleId 角色ID + * @return 结果 + */ + @Override + @Transactional + public int deleteRoleById(Long roleId) + { + // 删除角色与菜单关联 + roleMenuMapper.deleteRoleMenuByRoleId(roleId); + // 删除角色与部门关联 + roleDeptMapper.deleteRoleDeptByRoleId(roleId); + return roleMapper.deleteRoleById(roleId); + } + + /** + * 批量删除角色信息 + * + * @param roleIds 需要删除的角色ID + * @return 结果 + */ + @Override + @Transactional + public int deleteRoleByIds(Long[] roleIds) + { + for (Long roleId : roleIds) + { + checkRoleAllowed(new SysRole(roleId)); + checkRoleDataScope(roleId); + SysRole role = selectRoleById(roleId); + if (countUserRoleByRoleId(roleId) > 0) + { + throw new ServiceException(String.format("%1$s已分配,不能删除", role.getRoleName())); + } + } + // 删除角色与菜单关联 + roleMenuMapper.deleteRoleMenu(roleIds); + // 删除角色与部门关联 + roleDeptMapper.deleteRoleDept(roleIds); + return roleMapper.deleteRoleByIds(roleIds); + } + + /** + * 取消授权用户角色 + * + * @param userRole 用户和角色关联信息 + * @return 结果 + */ + @Override + public int deleteAuthUser(SysUserRole userRole) + { + return userRoleMapper.deleteUserRoleInfo(userRole); + } + + /** + * 批量取消授权用户角色 + * + * @param roleId 角色ID + * @param userIds 需要取消授权的用户数据ID + * @return 结果 + */ + @Override + public int deleteAuthUsers(Long roleId, Long[] userIds) + { + return userRoleMapper.deleteUserRoleInfos(roleId, userIds); + } + + /** + * 批量选择授权用户角色 + * + * @param roleId 角色ID + * @param userIds 需要授权的用户数据ID + * @return 结果 + */ + @Override + public int insertAuthUsers(Long roleId, Long[] userIds) + { + // 新增用户与角色管理 + List list = new ArrayList(); + for (Long userId : userIds) + { + SysUserRole ur = new SysUserRole(); + ur.setUserId(userId); + ur.setRoleId(roleId); + list.add(ur); + } + return userRoleMapper.batchUserRole(list); + } +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/service/impl/SysUserOnlineServiceImpl.java b/zzyl-system/src/main/java/com/zzyl/system/service/impl/SysUserOnlineServiceImpl.java new file mode 100644 index 0000000..568463c --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/service/impl/SysUserOnlineServiceImpl.java @@ -0,0 +1,96 @@ +package com.zzyl.system.service.impl; + +import org.springframework.stereotype.Service; +import com.zzyl.common.core.domain.model.LoginUser; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.system.domain.SysUserOnline; +import com.zzyl.system.service.ISysUserOnlineService; + +/** + * 在线用户 服务层处理 + * + * @author ruoyi + */ +@Service +public class SysUserOnlineServiceImpl implements ISysUserOnlineService +{ + /** + * 通过登录地址查询信息 + * + * @param ipaddr 登录地址 + * @param user 用户信息 + * @return 在线用户信息 + */ + @Override + public SysUserOnline selectOnlineByIpaddr(String ipaddr, LoginUser user) + { + if (StringUtils.equals(ipaddr, user.getIpaddr())) + { + return loginUserToUserOnline(user); + } + return null; + } + + /** + * 通过用户名称查询信息 + * + * @param userName 用户名称 + * @param user 用户信息 + * @return 在线用户信息 + */ + @Override + public SysUserOnline selectOnlineByUserName(String userName, LoginUser user) + { + if (StringUtils.equals(userName, user.getUsername())) + { + return loginUserToUserOnline(user); + } + return null; + } + + /** + * 通过登录地址/用户名称查询信息 + * + * @param ipaddr 登录地址 + * @param userName 用户名称 + * @param user 用户信息 + * @return 在线用户信息 + */ + @Override + public SysUserOnline selectOnlineByInfo(String ipaddr, String userName, LoginUser user) + { + if (StringUtils.equals(ipaddr, user.getIpaddr()) && StringUtils.equals(userName, user.getUsername())) + { + return loginUserToUserOnline(user); + } + return null; + } + + /** + * 设置在线用户信息 + * + * @param user 用户信息 + * @return 在线用户 + */ + @Override + public SysUserOnline loginUserToUserOnline(LoginUser user) + { + if (StringUtils.isNull(user) || StringUtils.isNull(user.getUser())) + { + return null; + } + SysUserOnline sysUserOnline = new SysUserOnline(); + sysUserOnline.setTokenId(user.getToken()); + sysUserOnline.setUserName(user.getUsername()); + sysUserOnline.setIpaddr(user.getIpaddr()); + sysUserOnline.setLoginLocation(user.getLoginLocation()); + sysUserOnline.setBrowser(user.getBrowser()); + sysUserOnline.setOs(user.getOs()); + sysUserOnline.setLoginTime(user.getLoginTime()); + if (StringUtils.isNotNull(user.getUser().getDept())) + { + sysUserOnline.setDeptName(user.getUser().getDept().getDeptName()); + } + return sysUserOnline; + } +} diff --git a/zzyl-system/src/main/java/com/zzyl/system/service/impl/SysUserServiceImpl.java b/zzyl-system/src/main/java/com/zzyl/system/service/impl/SysUserServiceImpl.java new file mode 100644 index 0000000..1b2bd23 --- /dev/null +++ b/zzyl-system/src/main/java/com/zzyl/system/service/impl/SysUserServiceImpl.java @@ -0,0 +1,562 @@ +package com.zzyl.system.service.impl; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import javax.validation.Validator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; +import com.zzyl.common.annotation.DataScope; +import com.zzyl.common.constant.UserConstants; +import com.zzyl.common.core.domain.entity.SysRole; +import com.zzyl.common.core.domain.entity.SysUser; +import com.zzyl.common.exception.ServiceException; +import com.zzyl.common.utils.SecurityUtils; +import com.zzyl.common.utils.StringUtils; +import com.zzyl.common.utils.bean.BeanValidators; +import com.zzyl.common.utils.spring.SpringUtils; +import com.zzyl.system.domain.SysPost; +import com.zzyl.system.domain.SysUserPost; +import com.zzyl.system.domain.SysUserRole; +import com.zzyl.system.mapper.SysPostMapper; +import com.zzyl.system.mapper.SysRoleMapper; +import com.zzyl.system.mapper.SysUserMapper; +import com.zzyl.system.mapper.SysUserPostMapper; +import com.zzyl.system.mapper.SysUserRoleMapper; +import com.zzyl.system.service.ISysConfigService; +import com.zzyl.system.service.ISysDeptService; +import com.zzyl.system.service.ISysUserService; + +/** + * 用户 业务层处理 + * + * @author ruoyi + */ +@Service +public class SysUserServiceImpl implements ISysUserService +{ + private static final Logger log = LoggerFactory.getLogger(SysUserServiceImpl.class); + + @Autowired + private SysUserMapper userMapper; + + @Autowired + private SysRoleMapper roleMapper; + + @Autowired + private SysPostMapper postMapper; + + @Autowired + private SysUserRoleMapper userRoleMapper; + + @Autowired + private SysUserPostMapper userPostMapper; + + @Autowired + private ISysConfigService configService; + + @Autowired + private ISysDeptService deptService; + + @Autowired + protected Validator validator; + + /** + * 根据条件分页查询用户列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + @Override + @DataScope(deptAlias = "d", userAlias = "u") + public List selectUserList(SysUser user) + { + return userMapper.selectUserList(user); + } + + /** + * 根据条件分页查询已分配用户角色列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + @Override + @DataScope(deptAlias = "d", userAlias = "u") + public List selectAllocatedList(SysUser user) + { + return userMapper.selectAllocatedList(user); + } + + /** + * 根据条件分页查询未分配用户角色列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + @Override + @DataScope(deptAlias = "d", userAlias = "u") + public List selectUnallocatedList(SysUser user) + { + return userMapper.selectUnallocatedList(user); + } + + /** + * 通过用户名查询用户 + * + * @param userName 用户名 + * @return 用户对象信息 + */ + @Override + public SysUser selectUserByUserName(String userName) + { + return userMapper.selectUserByUserName(userName); + } + + /** + * 通过用户ID查询用户 + * + * @param userId 用户ID + * @return 用户对象信息 + */ + @Override + public SysUser selectUserById(Long userId) + { + return userMapper.selectUserById(userId); + } + + /** + * 查询用户所属角色组 + * + * @param userName 用户名 + * @return 结果 + */ + @Override + public String selectUserRoleGroup(String userName) + { + List list = roleMapper.selectRolesByUserName(userName); + if (CollectionUtils.isEmpty(list)) + { + return StringUtils.EMPTY; + } + return list.stream().map(SysRole::getRoleName).collect(Collectors.joining(",")); + } + + /** + * 查询用户所属岗位组 + * + * @param userName 用户名 + * @return 结果 + */ + @Override + public String selectUserPostGroup(String userName) + { + List list = postMapper.selectPostsByUserName(userName); + if (CollectionUtils.isEmpty(list)) + { + return StringUtils.EMPTY; + } + return list.stream().map(SysPost::getPostName).collect(Collectors.joining(",")); + } + + /** + * 校验用户名称是否唯一 + * + * @param user 用户信息 + * @return 结果 + */ + @Override + public boolean checkUserNameUnique(SysUser user) + { + Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId(); + SysUser info = userMapper.checkUserNameUnique(user.getUserName()); + if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 校验手机号码是否唯一 + * + * @param user 用户信息 + * @return + */ + @Override + public boolean checkPhoneUnique(SysUser user) + { + Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId(); + SysUser info = userMapper.checkPhoneUnique(user.getPhonenumber()); + if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 校验email是否唯一 + * + * @param user 用户信息 + * @return + */ + @Override + public boolean checkEmailUnique(SysUser user) + { + Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId(); + SysUser info = userMapper.checkEmailUnique(user.getEmail()); + if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 校验用户是否允许操作 + * + * @param user 用户信息 + */ + @Override + public void checkUserAllowed(SysUser user) + { + if (StringUtils.isNotNull(user.getUserId()) && user.isAdmin()) + { + throw new ServiceException("不允许操作超级管理员用户"); + } + } + + /** + * 校验用户是否有数据权限 + * + * @param userId 用户id + */ + @Override + public void checkUserDataScope(Long userId) + { + if (!SysUser.isAdmin(SecurityUtils.getUserId())) + { + SysUser user = new SysUser(); + user.setUserId(userId); + List users = SpringUtils.getAopProxy(this).selectUserList(user); + if (StringUtils.isEmpty(users)) + { + throw new ServiceException("没有权限访问用户数据!"); + } + } + } + + /** + * 新增保存用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + @Override + @Transactional + public int insertUser(SysUser user) + { + // 新增用户信息 + int rows = userMapper.insertUser(user); + // 新增用户岗位关联 + insertUserPost(user); + // 新增用户与角色管理 + insertUserRole(user); + return rows; + } + + /** + * 注册用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + @Override + public boolean registerUser(SysUser user) + { + return userMapper.insertUser(user) > 0; + } + + /** + * 修改保存用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + @Override + @Transactional + public int updateUser(SysUser user) + { + Long userId = user.getUserId(); + // 删除用户与角色关联 + userRoleMapper.deleteUserRoleByUserId(userId); + // 新增用户与角色管理 + insertUserRole(user); + // 删除用户与岗位关联 + userPostMapper.deleteUserPostByUserId(userId); + // 新增用户与岗位管理 + insertUserPost(user); + return userMapper.updateUser(user); + } + + /** + * 用户授权角色 + * + * @param userId 用户ID + * @param roleIds 角色组 + */ + @Override + @Transactional + public void insertUserAuth(Long userId, Long[] roleIds) + { + userRoleMapper.deleteUserRoleByUserId(userId); + insertUserRole(userId, roleIds); + } + + /** + * 修改用户状态 + * + * @param user 用户信息 + * @return 结果 + */ + @Override + public int updateUserStatus(SysUser user) + { + return userMapper.updateUser(user); + } + + /** + * 修改用户基本信息 + * + * @param user 用户信息 + * @return 结果 + */ + @Override + public int updateUserProfile(SysUser user) + { + return userMapper.updateUser(user); + } + + /** + * 修改用户头像 + * + * @param userName 用户名 + * @param avatar 头像地址 + * @return 结果 + */ + @Override + public boolean updateUserAvatar(String userName, String avatar) + { + return userMapper.updateUserAvatar(userName, avatar) > 0; + } + + /** + * 重置用户密码 + * + * @param user 用户信息 + * @return 结果 + */ + @Override + public int resetPwd(SysUser user) + { + return userMapper.updateUser(user); + } + + /** + * 重置用户密码 + * + * @param userName 用户名 + * @param password 密码 + * @return 结果 + */ + @Override + public int resetUserPwd(String userName, String password) + { + return userMapper.resetUserPwd(userName, password); + } + + /** + * 新增用户角色信息 + * + * @param user 用户对象 + */ + public void insertUserRole(SysUser user) + { + this.insertUserRole(user.getUserId(), user.getRoleIds()); + } + + /** + * 新增用户岗位信息 + * + * @param user 用户对象 + */ + public void insertUserPost(SysUser user) + { + Long[] posts = user.getPostIds(); + if (StringUtils.isNotEmpty(posts)) + { + // 新增用户与岗位管理 + List list = new ArrayList(posts.length); + for (Long postId : posts) + { + SysUserPost up = new SysUserPost(); + up.setUserId(user.getUserId()); + up.setPostId(postId); + list.add(up); + } + userPostMapper.batchUserPost(list); + } + } + + /** + * 新增用户角色信息 + * + * @param userId 用户ID + * @param roleIds 角色组 + */ + public void insertUserRole(Long userId, Long[] roleIds) + { + if (StringUtils.isNotEmpty(roleIds)) + { + // 新增用户与角色管理 + List list = new ArrayList(roleIds.length); + for (Long roleId : roleIds) + { + SysUserRole ur = new SysUserRole(); + ur.setUserId(userId); + ur.setRoleId(roleId); + list.add(ur); + } + userRoleMapper.batchUserRole(list); + } + } + + /** + * 通过用户ID删除用户 + * + * @param userId 用户ID + * @return 结果 + */ + @Override + @Transactional + public int deleteUserById(Long userId) + { + // 删除用户与角色关联 + userRoleMapper.deleteUserRoleByUserId(userId); + // 删除用户与岗位表 + userPostMapper.deleteUserPostByUserId(userId); + return userMapper.deleteUserById(userId); + } + + /** + * 批量删除用户信息 + * + * @param userIds 需要删除的用户ID + * @return 结果 + */ + @Override + @Transactional + public int deleteUserByIds(Long[] userIds) + { + for (Long userId : userIds) + { + checkUserAllowed(new SysUser(userId)); + checkUserDataScope(userId); + } + // 删除用户与角色关联 + userRoleMapper.deleteUserRole(userIds); + // 删除用户与岗位关联 + userPostMapper.deleteUserPost(userIds); + return userMapper.deleteUserByIds(userIds); + } + + /** + * 导入用户数据 + * + * @param userList 用户数据列表 + * @param isUpdateSupport 是否更新支持,如果已存在,则进行更新数据 + * @param operName 操作用户 + * @return 结果 + */ + @Override + public String importUser(List userList, Boolean isUpdateSupport, String operName) + { + if (StringUtils.isNull(userList) || userList.size() == 0) + { + throw new ServiceException("导入用户数据不能为空!"); + } + int successNum = 0; + int failureNum = 0; + StringBuilder successMsg = new StringBuilder(); + StringBuilder failureMsg = new StringBuilder(); + for (SysUser user : userList) + { + try + { + // 验证是否存在这个用户 + SysUser u = userMapper.selectUserByUserName(user.getUserName()); + if (StringUtils.isNull(u)) + { + BeanValidators.validateWithException(validator, user); + deptService.checkDeptDataScope(user.getDeptId()); + String password = configService.selectConfigByKey("sys.user.initPassword"); + user.setPassword(SecurityUtils.encryptPassword(password)); + user.setCreateBy(operName); + userMapper.insertUser(user); + successNum++; + successMsg.append("
" + successNum + "、账号 " + user.getUserName() + " 导入成功"); + } + else if (isUpdateSupport) + { + BeanValidators.validateWithException(validator, user); + checkUserAllowed(u); + checkUserDataScope(u.getUserId()); + deptService.checkDeptDataScope(user.getDeptId()); + user.setUserId(u.getUserId()); + user.setUpdateBy(operName); + userMapper.updateUser(user); + successNum++; + successMsg.append("
" + successNum + "、账号 " + user.getUserName() + " 更新成功"); + } + else + { + failureNum++; + failureMsg.append("
" + failureNum + "、账号 " + user.getUserName() + " 已存在"); + } + } + catch (Exception e) + { + failureNum++; + String msg = "
" + failureNum + "、账号 " + user.getUserName() + " 导入失败:"; + failureMsg.append(msg + e.getMessage()); + log.error(msg, e); + } + } + if (failureNum > 0) + { + failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:"); + throw new ServiceException(failureMsg.toString()); + } + else + { + successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:"); + } + return successMsg.toString(); + } + + /** + * 根据部门编号查询员工列表 + * + * @param deptId + * @return + */ + @Override + public List getUserListByDept(Long deptId) { + List users = userMapper.getUserListByDept(deptId); + return users; + } +} diff --git a/zzyl-system/src/main/resources/mapper/system/SysConfigMapper.xml b/zzyl-system/src/main/resources/mapper/system/SysConfigMapper.xml new file mode 100644 index 0000000..8240cee --- /dev/null +++ b/zzyl-system/src/main/resources/mapper/system/SysConfigMapper.xml @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + select config_id, config_name, config_key, config_value, config_type, create_by, create_time, update_by, update_time, remark + from sys_config + + + + + + + and config_id = #{configId} + + + and config_key = #{configKey} + + + + + + + + + + + + + + insert into sys_config ( + config_name, + config_key, + config_value, + config_type, + create_by, + remark, + create_time + )values( + #{configName}, + #{configKey}, + #{configValue}, + #{configType}, + #{createBy}, + #{remark}, + sysdate() + ) + + + + update sys_config + + config_name = #{configName}, + config_key = #{configKey}, + config_value = #{configValue}, + config_type = #{configType}, + update_by = #{updateBy}, + remark = #{remark}, + update_time = sysdate() + + where config_id = #{configId} + + + + delete from sys_config where config_id = #{configId} + + + + delete from sys_config where config_id in + + #{configId} + + + + \ No newline at end of file diff --git a/zzyl-system/src/main/resources/mapper/system/SysDeptMapper.xml b/zzyl-system/src/main/resources/mapper/system/SysDeptMapper.xml new file mode 100644 index 0000000..9bc9d79 --- /dev/null +++ b/zzyl-system/src/main/resources/mapper/system/SysDeptMapper.xml @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + select d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.phone, d.email, d.status, d.del_flag, d.create_by, d.create_time + from sys_dept d + + + + + + + + + + + + + + + + + + + + insert into sys_dept( + dept_id, + parent_id, + dept_name, + ancestors, + order_num, + leader, + phone, + email, + status, + create_by, + create_time + )values( + #{deptId}, + #{parentId}, + #{deptName}, + #{ancestors}, + #{orderNum}, + #{leader}, + #{phone}, + #{email}, + #{status}, + #{createBy}, + sysdate() + ) + + + + update sys_dept + + parent_id = #{parentId}, + dept_name = #{deptName}, + ancestors = #{ancestors}, + order_num = #{orderNum}, + leader = #{leader}, + phone = #{phone}, + email = #{email}, + status = #{status}, + update_by = #{updateBy}, + update_time = sysdate() + + where dept_id = #{deptId} + + + + update sys_dept set ancestors = + + when #{item.deptId} then #{item.ancestors} + + where dept_id in + + #{item.deptId} + + + + + update sys_dept set status = '0' where dept_id in + + #{deptId} + + + + + update sys_dept set del_flag = '2' where dept_id = #{deptId} + + + \ No newline at end of file diff --git a/zzyl-system/src/main/resources/mapper/system/SysDictDataMapper.xml b/zzyl-system/src/main/resources/mapper/system/SysDictDataMapper.xml new file mode 100644 index 0000000..a58866a --- /dev/null +++ b/zzyl-system/src/main/resources/mapper/system/SysDictDataMapper.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + select dict_code, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, status, create_by, create_time, remark + from sys_dict_data + + + + + + + + + + + + + + delete from sys_dict_data where dict_code = #{dictCode} + + + + delete from sys_dict_data where dict_code in + + #{dictCode} + + + + + update sys_dict_data + + dict_sort = #{dictSort}, + dict_label = #{dictLabel}, + dict_value = #{dictValue}, + dict_type = #{dictType}, + css_class = #{cssClass}, + list_class = #{listClass}, + is_default = #{isDefault}, + status = #{status}, + remark = #{remark}, + update_by = #{updateBy}, + update_time = sysdate() + + where dict_code = #{dictCode} + + + + update sys_dict_data set dict_type = #{newDictType} where dict_type = #{oldDictType} + + + + insert into sys_dict_data( + dict_sort, + dict_label, + dict_value, + dict_type, + css_class, + list_class, + is_default, + status, + remark, + create_by, + create_time + )values( + #{dictSort}, + #{dictLabel}, + #{dictValue}, + #{dictType}, + #{cssClass}, + #{listClass}, + #{isDefault}, + #{status}, + #{remark}, + #{createBy}, + sysdate() + ) + + + \ No newline at end of file diff --git a/zzyl-system/src/main/resources/mapper/system/SysDictTypeMapper.xml b/zzyl-system/src/main/resources/mapper/system/SysDictTypeMapper.xml new file mode 100644 index 0000000..7bd31ac --- /dev/null +++ b/zzyl-system/src/main/resources/mapper/system/SysDictTypeMapper.xml @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + select dict_id, dict_name, dict_type, status, create_by, create_time, remark + from sys_dict_type + + + + + + + + + + + + + + delete from sys_dict_type where dict_id = #{dictId} + + + + delete from sys_dict_type where dict_id in + + #{dictId} + + + + + update sys_dict_type + + dict_name = #{dictName}, + dict_type = #{dictType}, + status = #{status}, + remark = #{remark}, + update_by = #{updateBy}, + update_time = sysdate() + + where dict_id = #{dictId} + + + + insert into sys_dict_type( + dict_name, + dict_type, + status, + remark, + create_by, + create_time + )values( + #{dictName}, + #{dictType}, + #{status}, + #{remark}, + #{createBy}, + sysdate() + ) + + + \ No newline at end of file diff --git a/zzyl-system/src/main/resources/mapper/system/SysLogininforMapper.xml b/zzyl-system/src/main/resources/mapper/system/SysLogininforMapper.xml new file mode 100644 index 0000000..d983092 --- /dev/null +++ b/zzyl-system/src/main/resources/mapper/system/SysLogininforMapper.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + insert into sys_logininfor (user_name, status, ipaddr, login_location, browser, os, msg, login_time) + values (#{userName}, #{status}, #{ipaddr}, #{loginLocation}, #{browser}, #{os}, #{msg}, sysdate()) + + + + + + delete from sys_logininfor where info_id in + + #{infoId} + + + + + truncate table sys_logininfor + + + \ No newline at end of file diff --git a/zzyl-system/src/main/resources/mapper/system/SysMenuMapper.xml b/zzyl-system/src/main/resources/mapper/system/SysMenuMapper.xml new file mode 100644 index 0000000..ad81332 --- /dev/null +++ b/zzyl-system/src/main/resources/mapper/system/SysMenuMapper.xml @@ -0,0 +1,206 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select menu_id, menu_name, parent_id, order_num, path, component, `query`, route_name, is_frame, is_cache, menu_type, visible, status, ifnull(perms,'') as perms, icon, create_time + from sys_menu + + + + + + + + + + + + + + + + + + + + + + + + + + update sys_menu + + menu_name = #{menuName}, + parent_id = #{parentId}, + order_num = #{orderNum}, + path = #{path}, + component = #{component}, + `query` = #{query}, + route_name = #{routeName}, + is_frame = #{isFrame}, + is_cache = #{isCache}, + menu_type = #{menuType}, + visible = #{visible}, + status = #{status}, + perms = #{perms}, + icon = #{icon}, + remark = #{remark}, + update_by = #{updateBy}, + update_time = sysdate() + + where menu_id = #{menuId} + + + + insert into sys_menu( + menu_id, + parent_id, + menu_name, + order_num, + path, + component, + `query`, + route_name, + is_frame, + is_cache, + menu_type, + visible, + status, + perms, + icon, + remark, + create_by, + create_time + )values( + #{menuId}, + #{parentId}, + #{menuName}, + #{orderNum}, + #{path}, + #{component}, + #{query}, + #{routeName}, + #{isFrame}, + #{isCache}, + #{menuType}, + #{visible}, + #{status}, + #{perms}, + #{icon}, + #{remark}, + #{createBy}, + sysdate() + ) + + + + delete from sys_menu where menu_id = #{menuId} + + + \ No newline at end of file diff --git a/zzyl-system/src/main/resources/mapper/system/SysNoticeMapper.xml b/zzyl-system/src/main/resources/mapper/system/SysNoticeMapper.xml new file mode 100644 index 0000000..8185d0b --- /dev/null +++ b/zzyl-system/src/main/resources/mapper/system/SysNoticeMapper.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + select notice_id, notice_title, notice_type, cast(notice_content as char) as notice_content, status, create_by, create_time, update_by, update_time, remark + from sys_notice + + + + + + + + insert into sys_notice ( + notice_title, + notice_type, + notice_content, + status, + remark, + create_by, + create_time + )values( + #{noticeTitle}, + #{noticeType}, + #{noticeContent}, + #{status}, + #{remark}, + #{createBy}, + sysdate() + ) + + + + update sys_notice + + notice_title = #{noticeTitle}, + notice_type = #{noticeType}, + notice_content = #{noticeContent}, + status = #{status}, + update_by = #{updateBy}, + update_time = sysdate() + + where notice_id = #{noticeId} + + + + delete from sys_notice where notice_id = #{noticeId} + + + + delete from sys_notice where notice_id in + + #{noticeId} + + + + \ No newline at end of file diff --git a/zzyl-system/src/main/resources/mapper/system/SysOperLogMapper.xml b/zzyl-system/src/main/resources/mapper/system/SysOperLogMapper.xml new file mode 100644 index 0000000..282de96 --- /dev/null +++ b/zzyl-system/src/main/resources/mapper/system/SysOperLogMapper.xml @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + select oper_id, title, business_type, method, request_method, operator_type, oper_name, dept_name, oper_url, oper_ip, oper_location, oper_param, json_result, status, error_msg, oper_time, cost_time + from sys_oper_log + + + + insert into sys_oper_log(title, business_type, method, request_method, operator_type, oper_name, dept_name, oper_url, oper_ip, oper_location, oper_param, json_result, status, error_msg, cost_time, oper_time) + values (#{title}, #{businessType}, #{method}, #{requestMethod}, #{operatorType}, #{operName}, #{deptName}, #{operUrl}, #{operIp}, #{operLocation}, #{operParam}, #{jsonResult}, #{status}, #{errorMsg}, #{costTime}, sysdate()) + + + + + + delete from sys_oper_log where oper_id in + + #{operId} + + + + + + + truncate table sys_oper_log + + + \ No newline at end of file diff --git a/zzyl-system/src/main/resources/mapper/system/SysPostMapper.xml b/zzyl-system/src/main/resources/mapper/system/SysPostMapper.xml new file mode 100644 index 0000000..cdcab7d --- /dev/null +++ b/zzyl-system/src/main/resources/mapper/system/SysPostMapper.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + select post_id, post_code, post_name, post_sort, status, create_by, create_time, remark + from sys_post + + + + + + + + + + + + + + + + + + update sys_post + + post_code = #{postCode}, + post_name = #{postName}, + post_sort = #{postSort}, + status = #{status}, + remark = #{remark}, + update_by = #{updateBy}, + update_time = sysdate() + + where post_id = #{postId} + + + + insert into sys_post( + post_id, + post_code, + post_name, + post_sort, + status, + remark, + create_by, + create_time + )values( + #{postId}, + #{postCode}, + #{postName}, + #{postSort}, + #{status}, + #{remark}, + #{createBy}, + sysdate() + ) + + + + delete from sys_post where post_id = #{postId} + + + + delete from sys_post where post_id in + + #{postId} + + + + \ No newline at end of file diff --git a/zzyl-system/src/main/resources/mapper/system/SysRoleDeptMapper.xml b/zzyl-system/src/main/resources/mapper/system/SysRoleDeptMapper.xml new file mode 100644 index 0000000..d8768de --- /dev/null +++ b/zzyl-system/src/main/resources/mapper/system/SysRoleDeptMapper.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + delete from sys_role_dept where role_id=#{roleId} + + + + + + delete from sys_role_dept where role_id in + + #{roleId} + + + + + insert into sys_role_dept(role_id, dept_id) values + + (#{item.roleId},#{item.deptId}) + + + + \ No newline at end of file diff --git a/zzyl-system/src/main/resources/mapper/system/SysRoleMapper.xml b/zzyl-system/src/main/resources/mapper/system/SysRoleMapper.xml new file mode 100644 index 0000000..73a42be --- /dev/null +++ b/zzyl-system/src/main/resources/mapper/system/SysRoleMapper.xml @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + select distinct r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.menu_check_strictly, r.dept_check_strictly, + r.status, r.del_flag, r.create_time, r.remark + from sys_role r + left join sys_user_role ur on ur.role_id = r.role_id + left join sys_user u on u.user_id = ur.user_id + left join sys_dept d on u.dept_id = d.dept_id + + + + + + + + + + + + + + + + + + + + insert into sys_role( + role_id, + role_name, + role_key, + role_sort, + data_scope, + menu_check_strictly, + dept_check_strictly, + status, + remark, + create_by, + create_time + )values( + #{roleId}, + #{roleName}, + #{roleKey}, + #{roleSort}, + #{dataScope}, + #{menuCheckStrictly}, + #{deptCheckStrictly}, + #{status}, + #{remark}, + #{createBy}, + sysdate() + ) + + + + update sys_role + + role_name = #{roleName}, + role_key = #{roleKey}, + role_sort = #{roleSort}, + data_scope = #{dataScope}, + menu_check_strictly = #{menuCheckStrictly}, + dept_check_strictly = #{deptCheckStrictly}, + status = #{status}, + remark = #{remark}, + update_by = #{updateBy}, + update_time = sysdate() + + where role_id = #{roleId} + + + + update sys_role set del_flag = '2' where role_id = #{roleId} + + + + update sys_role set del_flag = '2' where role_id in + + #{roleId} + + + + \ No newline at end of file diff --git a/zzyl-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml b/zzyl-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml new file mode 100644 index 0000000..682ffc4 --- /dev/null +++ b/zzyl-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + delete from sys_role_menu where role_id=#{roleId} + + + + delete from sys_role_menu where role_id in + + #{roleId} + + + + + insert into sys_role_menu(role_id, menu_id) values + + (#{item.roleId},#{item.menuId}) + + + + \ No newline at end of file diff --git a/zzyl-system/src/main/resources/mapper/system/SysUserMapper.xml b/zzyl-system/src/main/resources/mapper/system/SysUserMapper.xml new file mode 100644 index 0000000..f8add7c --- /dev/null +++ b/zzyl-system/src/main/resources/mapper/system/SysUserMapper.xml @@ -0,0 +1,221 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, + d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.status as dept_status, + r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.status as role_status + from sys_user u + left join sys_dept d on u.dept_id = d.dept_id + left join sys_user_role ur on u.user_id = ur.user_id + left join sys_role r on r.role_id = ur.role_id + + + + + + + + + + + + + + + + + + + + insert into sys_user( + user_id, + dept_id, + user_name, + nick_name, + email, + avatar, + phonenumber, + sex, + password, + status, + create_by, + remark, + create_time + )values( + #{userId}, + #{deptId}, + #{userName}, + #{nickName}, + #{email}, + #{avatar}, + #{phonenumber}, + #{sex}, + #{password}, + #{status}, + #{createBy}, + #{remark}, + sysdate() + ) + + + + update sys_user + + dept_id = #{deptId}, + user_name = #{userName}, + nick_name = #{nickName}, + email = #{email}, + phonenumber = #{phonenumber}, + sex = #{sex}, + avatar = #{avatar}, + password = #{password}, + status = #{status}, + login_ip = #{loginIp}, + login_date = #{loginDate}, + update_by = #{updateBy}, + remark = #{remark}, + update_time = sysdate() + + where user_id = #{userId} + + + + update sys_user set status = #{status} where user_id = #{userId} + + + + update sys_user set avatar = #{avatar} where user_name = #{userName} + + + + update sys_user set password = #{password} where user_name = #{userName} + + + + update sys_user set del_flag = '2' where user_id = #{userId} + + + + update sys_user set del_flag = '2' where user_id in + + #{userId} + + + + \ No newline at end of file diff --git a/zzyl-system/src/main/resources/mapper/system/SysUserPostMapper.xml b/zzyl-system/src/main/resources/mapper/system/SysUserPostMapper.xml new file mode 100644 index 0000000..e4ab5e2 --- /dev/null +++ b/zzyl-system/src/main/resources/mapper/system/SysUserPostMapper.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + delete from sys_user_post where user_id=#{userId} + + + + + + delete from sys_user_post where user_id in + + #{userId} + + + + + insert into sys_user_post(user_id, post_id) values + + (#{item.userId},#{item.postId}) + + + + \ No newline at end of file diff --git a/zzyl-system/src/main/resources/mapper/system/SysUserRoleMapper.xml b/zzyl-system/src/main/resources/mapper/system/SysUserRoleMapper.xml new file mode 100644 index 0000000..3fea1e8 --- /dev/null +++ b/zzyl-system/src/main/resources/mapper/system/SysUserRoleMapper.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + delete from sys_user_role where user_id=#{userId} + + + + + + + + delete from sys_user_role where user_id in + + #{userId} + + + + + insert into sys_user_role(user_id, role_id) values + + (#{item.userId},#{item.roleId}) + + + + + delete from sys_user_role where user_id=#{userId} and role_id=#{roleId} + + + + delete from sys_user_role where role_id=#{roleId} and user_id in + + #{userId} + + + \ No newline at end of file diff --git a/zzyl-ui/.dockerignore b/zzyl-ui/.dockerignore new file mode 100644 index 0000000..b20c500 --- /dev/null +++ b/zzyl-ui/.dockerignore @@ -0,0 +1,7 @@ +node_modules +dist +.git +.gitignore +.env.local +.env.*.local +*.log diff --git a/zzyl-ui/.editorconfig b/zzyl-ui/.editorconfig new file mode 100644 index 0000000..7034f9b --- /dev/null +++ b/zzyl-ui/.editorconfig @@ -0,0 +1,22 @@ +# 告诉EditorConfig插件,这是根文件,不用继续往上查找 +root = true + +# 匹配全部文件 +[*] +# 设置字符集 +charset = utf-8 +# 缩进风格,可选space、tab +indent_style = space +# 缩进的空格数 +indent_size = 2 +# 结尾换行符,可选lf、cr、crlf +end_of_line = lf +# 在文件结尾插入新行 +insert_final_newline = true +# 删除一行中的前后空格 +trim_trailing_whitespace = true + +# 匹配md结尾的文件 +[*.md] +insert_final_newline = false +trim_trailing_whitespace = false diff --git a/zzyl-ui/.env.development b/zzyl-ui/.env.development new file mode 100644 index 0000000..505f47a --- /dev/null +++ b/zzyl-ui/.env.development @@ -0,0 +1,11 @@ +# 页面标题 +VUE_APP_TITLE = 中州养老 + +# 开发环境配置 +ENV = 'development' + +# 中州养老/开发环境 +VUE_APP_BASE_API = '/dev-api' + +# 路由懒加载 +VUE_CLI_BABEL_TRANSPILE_MODULES = true diff --git a/zzyl-ui/.env.production b/zzyl-ui/.env.production new file mode 100644 index 0000000..544abb5 --- /dev/null +++ b/zzyl-ui/.env.production @@ -0,0 +1,8 @@ +# 页面标题 +VUE_APP_TITLE = 中州养老 + +# 生产环境配置 +ENV = 'production' + +# 中州养老/生产环境 +VUE_APP_BASE_API = '/prod-api' diff --git a/zzyl-ui/.env.staging b/zzyl-ui/.env.staging new file mode 100644 index 0000000..49168a5 --- /dev/null +++ b/zzyl-ui/.env.staging @@ -0,0 +1,10 @@ +# 页面标题 +VUE_APP_TITLE = 中州养老 + +NODE_ENV = production + +# 测试环境配置 +ENV = 'staging' + +# 中州养老/测试环境 +VUE_APP_BASE_API = '/stage-api' diff --git a/zzyl-ui/.eslintignore b/zzyl-ui/.eslintignore new file mode 100644 index 0000000..89be6f6 --- /dev/null +++ b/zzyl-ui/.eslintignore @@ -0,0 +1,10 @@ +# 忽略build目录下类型为js的文件的语法检查 +build/*.js +# 忽略src/assets目录下文件的语法检查 +src/assets +# 忽略public目录下文件的语法检查 +public +# 忽略当前目录下为js的文件的语法检查 +*.js +# 忽略当前目录下为vue的文件的语法检查 +*.vue \ No newline at end of file diff --git a/zzyl-ui/.eslintrc.js b/zzyl-ui/.eslintrc.js new file mode 100644 index 0000000..82bbdee --- /dev/null +++ b/zzyl-ui/.eslintrc.js @@ -0,0 +1,199 @@ +// ESlint 检查配置 +module.exports = { + root: true, + parserOptions: { + parser: 'babel-eslint', + sourceType: 'module' + }, + env: { + browser: true, + node: true, + es6: true, + }, + extends: ['plugin:vue/recommended', 'eslint:recommended'], + + // add your custom rules here + //it is base on https://github.com/vuejs/eslint-config-vue + rules: { + "vue/max-attributes-per-line": [2, { + "singleline": 10, + "multiline": { + "max": 1, + "allowFirstLine": false + } + }], + "vue/singleline-html-element-content-newline": "off", + "vue/multiline-html-element-content-newline":"off", + "vue/name-property-casing": ["error", "PascalCase"], + "vue/no-v-html": "off", + 'accessor-pairs': 2, + 'arrow-spacing': [2, { + 'before': true, + 'after': true + }], + 'block-spacing': [2, 'always'], + 'brace-style': [2, '1tbs', { + 'allowSingleLine': true + }], + 'camelcase': [0, { + 'properties': 'always' + }], + 'comma-dangle': [2, 'never'], + 'comma-spacing': [2, { + 'before': false, + 'after': true + }], + 'comma-style': [2, 'last'], + 'constructor-super': 2, + 'curly': [2, 'multi-line'], + 'dot-location': [2, 'property'], + 'eol-last': 2, + 'eqeqeq': ["error", "always", {"null": "ignore"}], + 'generator-star-spacing': [2, { + 'before': true, + 'after': true + }], + 'handle-callback-err': [2, '^(err|error)$'], + 'indent': [2, 2, { + 'SwitchCase': 1 + }], + 'jsx-quotes': [2, 'prefer-single'], + 'key-spacing': [2, { + 'beforeColon': false, + 'afterColon': true + }], + 'keyword-spacing': [2, { + 'before': true, + 'after': true + }], + 'new-cap': [2, { + 'newIsCap': true, + 'capIsNew': false + }], + 'new-parens': 2, + 'no-array-constructor': 2, + 'no-caller': 2, + 'no-console': 'off', + 'no-class-assign': 2, + 'no-cond-assign': 2, + 'no-const-assign': 2, + 'no-control-regex': 0, + 'no-delete-var': 2, + 'no-dupe-args': 2, + 'no-dupe-class-members': 2, + 'no-dupe-keys': 2, + 'no-duplicate-case': 2, + 'no-empty-character-class': 2, + 'no-empty-pattern': 2, + 'no-eval': 2, + 'no-ex-assign': 2, + 'no-extend-native': 2, + 'no-extra-bind': 2, + 'no-extra-boolean-cast': 2, + 'no-extra-parens': [2, 'functions'], + 'no-fallthrough': 2, + 'no-floating-decimal': 2, + 'no-func-assign': 2, + 'no-implied-eval': 2, + 'no-inner-declarations': [2, 'functions'], + 'no-invalid-regexp': 2, + 'no-irregular-whitespace': 2, + 'no-iterator': 2, + 'no-label-var': 2, + 'no-labels': [2, { + 'allowLoop': false, + 'allowSwitch': false + }], + 'no-lone-blocks': 2, + 'no-mixed-spaces-and-tabs': 2, + 'no-multi-spaces': 2, + 'no-multi-str': 2, + 'no-multiple-empty-lines': [2, { + 'max': 1 + }], + 'no-native-reassign': 2, + 'no-negated-in-lhs': 2, + 'no-new-object': 2, + 'no-new-require': 2, + 'no-new-symbol': 2, + 'no-new-wrappers': 2, + 'no-obj-calls': 2, + 'no-octal': 2, + 'no-octal-escape': 2, + 'no-path-concat': 2, + 'no-proto': 2, + 'no-redeclare': 2, + 'no-regex-spaces': 2, + 'no-return-assign': [2, 'except-parens'], + 'no-self-assign': 2, + 'no-self-compare': 2, + 'no-sequences': 2, + 'no-shadow-restricted-names': 2, + 'no-spaced-func': 2, + 'no-sparse-arrays': 2, + 'no-this-before-super': 2, + 'no-throw-literal': 2, + 'no-trailing-spaces': 2, + 'no-undef': 2, + 'no-undef-init': 2, + 'no-unexpected-multiline': 2, + 'no-unmodified-loop-condition': 2, + 'no-unneeded-ternary': [2, { + 'defaultAssignment': false + }], + 'no-unreachable': 2, + 'no-unsafe-finally': 2, + 'no-unused-vars': [2, { + 'vars': 'all', + 'args': 'none' + }], + 'no-useless-call': 2, + 'no-useless-computed-key': 2, + 'no-useless-constructor': 2, + 'no-useless-escape': 0, + 'no-whitespace-before-property': 2, + 'no-with': 2, + 'one-var': [2, { + 'initialized': 'never' + }], + 'operator-linebreak': [2, 'after', { + 'overrides': { + '?': 'before', + ':': 'before' + } + }], + 'padded-blocks': [2, 'never'], + 'quotes': [2, 'single', { + 'avoidEscape': true, + 'allowTemplateLiterals': true + }], + 'semi': [2, 'never'], + 'semi-spacing': [2, { + 'before': false, + 'after': true + }], + 'space-before-blocks': [2, 'always'], + 'space-before-function-paren': [2, 'never'], + 'space-in-parens': [2, 'never'], + 'space-infix-ops': 2, + 'space-unary-ops': [2, { + 'words': true, + 'nonwords': false + }], + 'spaced-comment': [2, 'always', { + 'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ','] + }], + 'template-curly-spacing': [2, 'never'], + 'use-isnan': 2, + 'valid-typeof': 2, + 'wrap-iife': [2, 'any'], + 'yield-star-spacing': [2, 'both'], + 'yoda': [2, 'never'], + 'prefer-const': 2, + 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0, + 'object-curly-spacing': [2, 'always', { + objectsInObjects: false + }], + 'array-bracket-spacing': [2, 'never'] + } +} diff --git a/zzyl-ui/.gitignore b/zzyl-ui/.gitignore new file mode 100644 index 0000000..78a752d --- /dev/null +++ b/zzyl-ui/.gitignore @@ -0,0 +1,23 @@ +.DS_Store +node_modules/ +dist/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* +**/*.log + +tests/**/coverage/ +tests/e2e/reports +selenium-debug.log + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln +*.local + +package-lock.json +yarn.lock diff --git a/zzyl-ui/Dockerfile b/zzyl-ui/Dockerfile new file mode 100644 index 0000000..2e84e31 --- /dev/null +++ b/zzyl-ui/Dockerfile @@ -0,0 +1,20 @@ +FROM node:18-alpine AS build + +WORKDIR /app + +ENV NODE_OPTIONS=--openssl-legacy-provider + +RUN corepack enable && corepack prepare pnpm@10.33.0 --activate + +COPY package.json pnpm-lock.yaml ./ +RUN pnpm install --frozen-lockfile + +COPY . . +RUN pnpm build:prod + +FROM nginx:1.27-alpine + +COPY nginx.conf /etc/nginx/conf.d/default.conf +COPY --from=build /app/dist /usr/share/nginx/html + +EXPOSE 80 diff --git a/zzyl-ui/README.md b/zzyl-ui/README.md new file mode 100644 index 0000000..2eb4b61 --- /dev/null +++ b/zzyl-ui/README.md @@ -0,0 +1,27 @@ +## 开发 + +```bash +# 克隆项目 +git clone https://gitee.com/y_project/RuoYi-Vue + +# 进入项目目录 +cd zzyl-ui + +# 安装依赖 +pnpm install + +# 启动服务 +pnpm dev +``` + +浏览器访问 http://localhost:80 + +## 发布 + +```bash +# 构建测试环境 +pnpm build:stage + +# 构建生产环境 +pnpm build:prod +``` diff --git a/zzyl-ui/babel.config.js b/zzyl-ui/babel.config.js new file mode 100644 index 0000000..c8267b2 --- /dev/null +++ b/zzyl-ui/babel.config.js @@ -0,0 +1,13 @@ +module.exports = { + presets: [ + // https://github.com/vuejs/vue-cli/tree/master/packages/@vue/babel-preset-app + '@vue/cli-plugin-babel/preset' + ], + 'env': { + 'development': { + // babel-plugin-dynamic-import-node plugin only does one thing by converting all import() to require(). + // This plugin can significantly increase the speed of hot updates, when you have a large number of pages. + 'plugins': ['dynamic-import-node'] + } + } +} \ No newline at end of file diff --git a/zzyl-ui/bin/build.bat b/zzyl-ui/bin/build.bat new file mode 100644 index 0000000..dda590d --- /dev/null +++ b/zzyl-ui/bin/build.bat @@ -0,0 +1,12 @@ +@echo off +echo. +echo [Ϣ] Weḅdistļ +echo. + +%~d0 +cd %~dp0 + +cd .. +npm run build:prod + +pause \ No newline at end of file diff --git a/zzyl-ui/bin/package.bat b/zzyl-ui/bin/package.bat new file mode 100644 index 0000000..0e5bc0f --- /dev/null +++ b/zzyl-ui/bin/package.bat @@ -0,0 +1,12 @@ +@echo off +echo. +echo [Ϣ] װWeḅnode_modulesļ +echo. + +%~d0 +cd %~dp0 + +cd .. +npm install --registry=https://registry.npmmirror.com + +pause \ No newline at end of file diff --git a/zzyl-ui/bin/run-web.bat b/zzyl-ui/bin/run-web.bat new file mode 100644 index 0000000..d30deae --- /dev/null +++ b/zzyl-ui/bin/run-web.bat @@ -0,0 +1,12 @@ +@echo off +echo. +echo [Ϣ] ʹ Vue CLI Web ̡ +echo. + +%~d0 +cd %~dp0 + +cd .. +npm run dev + +pause \ No newline at end of file diff --git a/zzyl-ui/build/index.js b/zzyl-ui/build/index.js new file mode 100644 index 0000000..0c57de2 --- /dev/null +++ b/zzyl-ui/build/index.js @@ -0,0 +1,35 @@ +const { run } = require('runjs') +const chalk = require('chalk') +const config = require('../vue.config.js') +const rawArgv = process.argv.slice(2) +const args = rawArgv.join(' ') + +if (process.env.npm_config_preview || rawArgv.includes('--preview')) { + const report = rawArgv.includes('--report') + + run(`vue-cli-service build ${args}`) + + const port = 9526 + const publicPath = config.publicPath + + var connect = require('connect') + var serveStatic = require('serve-static') + const app = connect() + + app.use( + publicPath, + serveStatic('./dist', { + index: ['index.html', '/'] + }) + ) + + app.listen(port, function () { + console.log(chalk.green(`> Preview at http://localhost:${port}${publicPath}`)) + if (report) { + console.log(chalk.green(`> Report at http://localhost:${port}${publicPath}report.html`)) + } + + }) +} else { + run(`vue-cli-service build ${args}`) +} diff --git a/zzyl-ui/nginx.conf b/zzyl-ui/nginx.conf new file mode 100644 index 0000000..38ad74a --- /dev/null +++ b/zzyl-ui/nginx.conf @@ -0,0 +1,26 @@ +server { + listen 80; + server_name _; + + root /usr/share/nginx/html; + index index.html; + + client_max_body_size 20m; + + gzip_static on; + + location / { + try_files $uri $uri/ /index.html; + } + + location /prod-api/ { + proxy_pass http://zzyl-admin:9000/; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + } +} diff --git a/zzyl-ui/package.json b/zzyl-ui/package.json new file mode 100644 index 0000000..c489fb5 --- /dev/null +++ b/zzyl-ui/package.json @@ -0,0 +1,91 @@ +{ + "name": "ruoyi", + "version": "3.8.8", + "description": "中州养老", + "author": "若依", + "license": "MIT", + "scripts": { + "dev": "vue-cli-service serve", + "build:prod": "vue-cli-service build", + "build:stage": "vue-cli-service build --mode staging", + "preview": "node build/index.js --preview", + "lint": "eslint --ext .js,.vue src" + }, + "husky": { + "hooks": { + "pre-commit": "lint-staged" + } + }, + "lint-staged": { + "src/**/*.{js,vue}": [ + "eslint --fix", + "git add" + ] + }, + "keywords": [ + "vue", + "admin", + "dashboard", + "element-ui", + "boilerplate", + "admin-template", + "management-system" + ], + "repository": { + "type": "git", + "url": "https://gitee.com/y_project/RuoYi-Vue.git" + }, + "dependencies": { + "@riophae/vue-treeselect": "0.4.0", + "axios": "0.28.1", + "clipboard": "2.0.8", + "core-js": "3.37.1", + "echarts": "5.4.0", + "element-ui": "2.15.14", + "file-saver": "2.0.5", + "fuse.js": "6.4.3", + "highlight.js": "9.18.5", + "js-beautify": "1.13.0", + "js-cookie": "3.0.1", + "jsencrypt": "3.0.0-rc.1", + "nprogress": "0.2.0", + "quill": "1.3.7", + "screenfull": "5.0.2", + "sortablejs": "1.10.2", + "vue": "2.6.12", + "vue-count-to": "1.0.13", + "vue-cropper": "0.5.5", + "vue-meta": "2.4.0", + "vue-router": "3.4.9", + "vuedraggable": "2.24.3", + "vuex": "3.6.0" + }, + "devDependencies": { + "@vue/cli-plugin-babel": "4.4.6", + "@vue/cli-plugin-eslint": "4.4.6", + "@vue/cli-service": "4.4.6", + "babel-eslint": "10.1.0", + "babel-plugin-dynamic-import-node": "2.3.3", + "chalk": "4.1.0", + "compression-webpack-plugin": "6.1.2", + "connect": "3.6.6", + "eslint": "7.15.0", + "eslint-plugin-vue": "7.2.0", + "lint-staged": "10.5.3", + "runjs": "4.4.2", + "sass": "1.32.13", + "sass-loader": "10.1.1", + "script-ext-html-webpack-plugin": "2.1.5", + "svg-sprite-loader": "5.1.1", + "vue-template-compiler": "2.6.12" + }, + "engines": { + "node": ">=8.9", + "npm": ">= 3.0.0" + }, + "browserslist": [ + "> 1%", + "last 2 versions" + ], + "packageManager": "pnpm@10.33.0+sha512.10568bb4a6afb58c9eb3630da90cc9516417abebd3fabbe6739f0ae795728da1491e9db5a544c76ad8eb7570f5c4bb3d6c637b2cb41bfdcdb47fa823c8649319" +} diff --git a/zzyl-ui/pnpm-lock.yaml b/zzyl-ui/pnpm-lock.yaml new file mode 100644 index 0000000..85e1e5d --- /dev/null +++ b/zzyl-ui/pnpm-lock.yaml @@ -0,0 +1,12376 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@riophae/vue-treeselect': + specifier: 0.4.0 + version: 0.4.0(vue@2.6.12) + axios: + specifier: 0.28.1 + version: 0.28.1 + clipboard: + specifier: 2.0.8 + version: 2.0.8 + core-js: + specifier: 3.37.1 + version: 3.37.1 + echarts: + specifier: 5.4.0 + version: 5.4.0 + element-ui: + specifier: 2.15.14 + version: 2.15.14(vue@2.6.12) + file-saver: + specifier: 2.0.5 + version: 2.0.5 + fuse.js: + specifier: 6.4.3 + version: 6.4.3 + highlight.js: + specifier: 9.18.5 + version: 9.18.5 + js-beautify: + specifier: 1.13.0 + version: 1.13.0 + js-cookie: + specifier: 3.0.1 + version: 3.0.1 + jsencrypt: + specifier: 3.0.0-rc.1 + version: 3.0.0-rc.1 + nprogress: + specifier: 0.2.0 + version: 0.2.0 + quill: + specifier: 1.3.7 + version: 1.3.7 + screenfull: + specifier: 5.0.2 + version: 5.0.2 + sortablejs: + specifier: 1.10.2 + version: 1.10.2 + vue: + specifier: 2.6.12 + version: 2.6.12 + vue-count-to: + specifier: 1.0.13 + version: 1.0.13 + vue-cropper: + specifier: 0.5.5 + version: 0.5.5 + vue-meta: + specifier: 2.4.0 + version: 2.4.0 + vue-router: + specifier: 3.4.9 + version: 3.4.9(vue@2.6.12) + vuedraggable: + specifier: 2.24.3 + version: 2.24.3 + vuex: + specifier: 3.6.0 + version: 3.6.0(vue@2.6.12) + devDependencies: + '@vue/cli-plugin-babel': + specifier: 4.4.6 + version: 4.4.6(@vue/cli-service@4.4.6(@vue/compiler-sfc@3.5.33)(lodash@4.18.1)(sass-loader@10.1.1(sass@1.32.13)(webpack@4.47.0))(vue-template-compiler@2.6.12))(core-js@3.37.1)(vue@2.6.12) + '@vue/cli-plugin-eslint': + specifier: 4.4.6 + version: 4.4.6(@vue/cli-service@4.4.6(@vue/compiler-sfc@3.5.33)(lodash@4.18.1)(sass-loader@10.1.1(sass@1.32.13)(webpack@4.47.0))(vue-template-compiler@2.6.12))(eslint@7.15.0) + '@vue/cli-service': + specifier: 4.4.6 + version: 4.4.6(@vue/compiler-sfc@3.5.33)(lodash@4.18.1)(sass-loader@10.1.1(sass@1.32.13)(webpack@4.47.0))(vue-template-compiler@2.6.12) + babel-eslint: + specifier: 10.1.0 + version: 10.1.0(eslint@7.15.0) + babel-plugin-dynamic-import-node: + specifier: 2.3.3 + version: 2.3.3 + chalk: + specifier: 4.1.0 + version: 4.1.0 + compression-webpack-plugin: + specifier: 6.1.2 + version: 6.1.2(webpack@4.47.0) + connect: + specifier: 3.6.6 + version: 3.6.6 + eslint: + specifier: 7.15.0 + version: 7.15.0 + eslint-plugin-vue: + specifier: 7.2.0 + version: 7.2.0(eslint@7.15.0) + lint-staged: + specifier: 10.5.3 + version: 10.5.3 + runjs: + specifier: 4.4.2 + version: 4.4.2 + sass: + specifier: 1.32.13 + version: 1.32.13 + sass-loader: + specifier: 10.1.1 + version: 10.1.1(sass@1.32.13)(webpack@4.47.0) + script-ext-html-webpack-plugin: + specifier: 2.1.5 + version: 2.1.5(html-webpack-plugin@3.2.0(webpack@4.47.0))(webpack@4.47.0) + svg-sprite-loader: + specifier: 5.1.1 + version: 5.1.1(webpack@4.47.0) + vue-template-compiler: + specifier: 2.6.12 + version: 2.6.12 + +packages: + + '@achrinza/node-ipc@9.2.2': + resolution: {integrity: sha512-b90U39dx0cU6emsOvy5hxU4ApNXnE3+Tuo8XQZfiKTGelDwpMwBVgBP7QX6dGTcJgu/miyJuNJ/2naFBliNWEw==} + engines: {node: 8 || 10 || 12 || 14 || 16 || 17} + + '@babel/code-frame@7.29.0': + resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.29.0': + resolution: {integrity: sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.29.0': + resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.29.1': + resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-annotate-as-pure@7.27.3': + resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.28.6': + resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-create-class-features-plugin@7.28.6': + resolution: {integrity: sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-create-regexp-features-plugin@7.28.5': + resolution: {integrity: sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-define-polyfill-provider@0.6.8': + resolution: {integrity: sha512-47UwBLPpQi1NoWzLuHNjRoHlYXMwIJoBf7MFou6viC/sIHWYygpvr0B6IAyh5sBdA2nr2LPIRww8lfaUVQINBA==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + '@babel/helper-globals@7.28.0': + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-member-expression-to-functions@7.28.5': + resolution: {integrity: sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.28.6': + resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.28.6': + resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-optimise-call-expression@7.27.1': + resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-plugin-utils@7.28.6': + resolution: {integrity: sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==} + engines: {node: '>=6.9.0'} + + '@babel/helper-remap-async-to-generator@7.27.1': + resolution: {integrity: sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-replace-supers@7.28.6': + resolution: {integrity: sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + resolution: {integrity: sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-wrap-function@7.28.6': + resolution: {integrity: sha512-z+PwLziMNBeSQJonizz2AGnndLsP2DeGHIxDAn+wdHOGuo4Fo1x1HBPPXeE9TAOPHNNWQKCSlA2VZyYyyibDnQ==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.29.2': + resolution: {integrity: sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.29.2': + resolution: {integrity: sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5': + resolution: {integrity: sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1': + resolution: {integrity: sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1': + resolution: {integrity: sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1': + resolution: {integrity: sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.13.0 + + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.6': + resolution: {integrity: sha512-a0aBScVTlNaiUe35UtfxAN7A/tehvvG4/ByO6+46VPKTRSlfnAFsgKy0FUh+qAkQrDTmhDkT+IBOKlOoMUxQ0g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-proposal-class-properties@7.18.6': + resolution: {integrity: sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==} + engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead. + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-proposal-decorators@7.29.0': + resolution: {integrity: sha512-CVBVv3VY/XRMxRYq5dwr2DS7/MvqPm23cOCjbwNnVrfOqcWlnefua1uUs0sjdKOGjvPUG633o07uWzJq4oI6dA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2': + resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-decorators@7.28.6': + resolution: {integrity: sha512-71EYI0ONURHJBL4rSFXnITXqXrrY8q4P0q006DPfN+Rk+ASM+++IBXem/ruokgBZR8YNEWZ8R6B+rCb8VcUTqA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-dynamic-import@7.8.3': + resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-assertions@7.28.6': + resolution: {integrity: sha512-pSJUpFHdx9z5nqTSirOCMtYVP2wFgoWhP0p3g8ONK/4IHhLIBd0B9NYqAvIUAhq+OkhO4VM1tENCt0cjlsNShw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-attributes@7.28.6': + resolution: {integrity: sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-jsx@7.28.6': + resolution: {integrity: sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-unicode-sets-regex@7.18.6': + resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-transform-arrow-functions@7.27.1': + resolution: {integrity: sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-async-generator-functions@7.29.0': + resolution: {integrity: sha512-va0VdWro4zlBr2JsXC+ofCPB2iG12wPtVGTWFx2WLDOM3nYQZZIGP82qku2eW/JR83sD+k2k+CsNtyEbUqhU6w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-async-to-generator@7.28.6': + resolution: {integrity: sha512-ilTRcmbuXjsMmcZ3HASTe4caH5Tpo93PkTxF9oG2VZsSWsahydmcEHhix9Ik122RcTnZnUzPbmux4wh1swfv7g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-block-scoped-functions@7.27.1': + resolution: {integrity: sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-block-scoping@7.28.6': + resolution: {integrity: sha512-tt/7wOtBmwHPNMPu7ax4pdPz6shjFrmHDghvNC+FG9Qvj7D6mJcoRQIF5dy4njmxR941l6rgtvfSB2zX3VlUIw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-class-properties@7.28.6': + resolution: {integrity: sha512-dY2wS3I2G7D697VHndN91TJr8/AAfXQNt5ynCTI/MpxMsSzHp+52uNivYT5wCPax3whc47DR8Ba7cmlQMg24bw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-class-static-block@7.28.6': + resolution: {integrity: sha512-rfQ++ghVwTWTqQ7w8qyDxL1XGihjBss4CmTgGRCTAC9RIbhVpyp4fOeZtta0Lbf+dTNIVJer6ych2ibHwkZqsQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.12.0 + + '@babel/plugin-transform-classes@7.28.6': + resolution: {integrity: sha512-EF5KONAqC5zAqT783iMGuM2ZtmEBy+mJMOKl2BCvPZ2lVrwvXnB6o+OBWCS+CoeCCpVRF2sA2RBKUxvT8tQT5Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-computed-properties@7.28.6': + resolution: {integrity: sha512-bcc3k0ijhHbc2lEfpFHgx7eYw9KNXqOerKWfzbxEHUGKnS3sz9C4CNL9OiFN1297bDNfUiSO7DaLzbvHQQQ1BQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-destructuring@7.28.5': + resolution: {integrity: sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-dotall-regex@7.28.6': + resolution: {integrity: sha512-SljjowuNKB7q5Oayv4FoPzeB74g3QgLt8IVJw9ADvWy3QnUb/01aw8I4AVv8wYnPvQz2GDDZ/g3GhcNyDBI4Bg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-duplicate-keys@7.27.1': + resolution: {integrity: sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.29.0': + resolution: {integrity: sha512-zBPcW2lFGxdiD8PUnPwJjag2J9otbcLQzvbiOzDxpYXyCuYX9agOwMPGn1prVH0a4qzhCKu24rlH4c1f7yA8rw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-transform-dynamic-import@7.27.1': + resolution: {integrity: sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-explicit-resource-management@7.28.6': + resolution: {integrity: sha512-Iao5Konzx2b6g7EPqTy40UZbcdXE126tTxVFr/nAIj+WItNxjKSYTEw3RC+A2/ZetmdJsgueL1KhaMCQHkLPIg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-exponentiation-operator@7.28.6': + resolution: {integrity: sha512-WitabqiGjV/vJ0aPOLSFfNY1u9U3R7W36B03r5I2KoNix+a3sOhJ3pKFB3R5It9/UiK78NiO0KE9P21cMhlPkw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-export-namespace-from@7.27.1': + resolution: {integrity: sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-for-of@7.27.1': + resolution: {integrity: sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-function-name@7.27.1': + resolution: {integrity: sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-json-strings@7.28.6': + resolution: {integrity: sha512-Nr+hEN+0geQkzhbdgQVPoqr47lZbm+5fCUmO70722xJZd0Mvb59+33QLImGj6F+DkK3xgDi1YVysP8whD6FQAw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-literals@7.27.1': + resolution: {integrity: sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-logical-assignment-operators@7.28.6': + resolution: {integrity: sha512-+anKKair6gpi8VsM/95kmomGNMD0eLz1NQ8+Pfw5sAwWH9fGYXT50E55ZpV0pHUHWf6IUTWPM+f/7AAff+wr9A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-member-expression-literals@7.27.1': + resolution: {integrity: sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-amd@7.27.1': + resolution: {integrity: sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-commonjs@7.28.6': + resolution: {integrity: sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-systemjs@7.29.0': + resolution: {integrity: sha512-PrujnVFbOdUpw4UHiVwKvKRLMMic8+eC0CuNlxjsyZUiBjhFdPsewdXCkveh2KqBA9/waD0W1b4hXSOBQJezpQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-umd@7.27.1': + resolution: {integrity: sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-named-capturing-groups-regex@7.29.0': + resolution: {integrity: sha512-1CZQA5KNAD6ZYQLPw7oi5ewtDNxH/2vuCh+6SmvgDfhumForvs8a1o9n0UrEoBD8HU4djO2yWngTQlXl1NDVEQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-transform-new-target@7.27.1': + resolution: {integrity: sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-nullish-coalescing-operator@7.28.6': + resolution: {integrity: sha512-3wKbRgmzYbw24mDJXT7N+ADXw8BC/imU9yo9c9X9NKaLF1fW+e5H1U5QjMUBe4Qo4Ox/o++IyUkl1sVCLgevKg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-numeric-separator@7.28.6': + resolution: {integrity: sha512-SJR8hPynj8outz+SlStQSwvziMN4+Bq99it4tMIf5/Caq+3iOc0JtKyse8puvyXkk3eFRIA5ID/XfunGgO5i6w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-object-rest-spread@7.28.6': + resolution: {integrity: sha512-5rh+JR4JBC4pGkXLAcYdLHZjXudVxWMXbB6u6+E9lRL5TrGVbHt1TjxGbZ8CkmYw9zjkB7jutzOROArsqtncEA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-object-super@7.27.1': + resolution: {integrity: sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-optional-catch-binding@7.28.6': + resolution: {integrity: sha512-R8ja/Pyrv0OGAvAXQhSTmWyPJPml+0TMqXlO5w+AsMEiwb2fg3WkOvob7UxFSL3OIttFSGSRFKQsOhJ/X6HQdQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-optional-chaining@7.28.6': + resolution: {integrity: sha512-A4zobikRGJTsX9uqVFdafzGkqD30t26ck2LmOzAuLL8b2x6k3TIqRiT2xVvA9fNmFeTX484VpsdgmKNA0bS23w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-parameters@7.27.7': + resolution: {integrity: sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-private-methods@7.28.6': + resolution: {integrity: sha512-piiuapX9CRv7+0st8lmuUlRSmX6mBcVeNQ1b4AYzJxfCMuBfB0vBXDiGSmm03pKJw1v6cZ8KSeM+oUnM6yAExg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-private-property-in-object@7.28.6': + resolution: {integrity: sha512-b97jvNSOb5+ehyQmBpmhOCiUC5oVK4PMnpRvO7+ymFBoqYjeDHIU9jnrNUuwHOiL9RpGDoKBpSViarV+BU+eVA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-property-literals@7.27.1': + resolution: {integrity: sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-regenerator@7.29.0': + resolution: {integrity: sha512-FijqlqMA7DmRdg/aINBSs04y8XNTYw/lr1gJ2WsmBnnaNw1iS43EPkJW+zK7z65auG3AWRFXWj+NcTQwYptUog==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-regexp-modifiers@7.28.6': + resolution: {integrity: sha512-QGWAepm9qxpaIs7UM9FvUSnCGlb8Ua1RhyM4/veAxLwt3gMat/LSGrZixyuj4I6+Kn9iwvqCyPTtbdxanYoWYg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-transform-reserved-words@7.27.1': + resolution: {integrity: sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-runtime@7.29.0': + resolution: {integrity: sha512-jlaRT5dJtMaMCV6fAuLbsQMSwz/QkvaHOHOSXRitGGwSpR1blCY4KUKoyP2tYO8vJcqYe8cEj96cqSztv3uF9w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-shorthand-properties@7.27.1': + resolution: {integrity: sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-spread@7.28.6': + resolution: {integrity: sha512-9U4QObUC0FtJl05AsUcodau/RWDytrU6uKgkxu09mLR9HLDAtUMoPuuskm5huQsoktmsYpI+bGmq+iapDcriKA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-sticky-regex@7.27.1': + resolution: {integrity: sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-template-literals@7.27.1': + resolution: {integrity: sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-typeof-symbol@7.27.1': + resolution: {integrity: sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-escapes@7.27.1': + resolution: {integrity: sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-property-regex@7.28.6': + resolution: {integrity: sha512-4Wlbdl/sIZjzi/8St0evF0gEZrgOswVO6aOzqxh1kDZOl9WmLrHq2HtGhnOJZmHZYKP8WZ1MDLCt5DAWwRo57A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-regex@7.27.1': + resolution: {integrity: sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-sets-regex@7.28.6': + resolution: {integrity: sha512-/wHc/paTUmsDYN7SZkpWxogTOBNnlx7nBQYfy6JJlCT7G3mVhltk3e++N7zV0XfgGsrqBxd4rJQt9H16I21Y1Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/preset-env@7.29.2': + resolution: {integrity: sha512-DYD23veRYGvBFhcTY1iUvJnDNpuqNd/BzBwCvzOTKUnJjKg5kpUBh3/u9585Agdkgj+QuygG7jLfOPWMa2KVNw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/preset-modules@0.1.6-no-external-plugins': + resolution: {integrity: sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==} + peerDependencies: + '@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0 + + '@babel/runtime@7.29.2': + resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==} + engines: {node: '>=6.9.0'} + + '@babel/template@7.28.6': + resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.29.0': + resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.29.0': + resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} + engines: {node: '>=6.9.0'} + + '@eslint/eslintrc@0.2.2': + resolution: {integrity: sha512-EfB5OHNYp1F4px/LI/FEnGylop7nOqkQ1LRzCM0KccA2U8tvV8w01KBv37LbO7nW4H+YhKyo2LcJhRwjjV17QQ==} + engines: {node: ^10.12.0 || >=12.0.0} + + '@gar/promisify@1.1.3': + resolution: {integrity: sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==} + + '@hapi/address@2.1.4': + resolution: {integrity: sha512-QD1PhQk+s31P1ixsX0H0Suoupp3VMXzIVMSwobR3F3MSUO2YCV0B7xqLcUw/Bh8yuvd3LhpyqLQWTNcRmp6IdQ==} + deprecated: Moved to 'npm install @sideway/address' + + '@hapi/bourne@1.3.2': + resolution: {integrity: sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA==} + deprecated: This version has been deprecated and is no longer supported or maintained + + '@hapi/hoek@8.5.1': + resolution: {integrity: sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow==} + deprecated: This version has been deprecated and is no longer supported or maintained + + '@hapi/joi@15.1.1': + resolution: {integrity: sha512-entf8ZMOK8sc+8YfeOlM8pCfg3b5+WZIKBfUaaJT8UsjAAPjartzxIYm3TIbjvA4u+u++KbcXD38k682nVHDAQ==} + deprecated: Switch to 'npm install joi' + + '@hapi/topo@3.1.6': + resolution: {integrity: sha512-tAag0jEcjwH+P2quUfipd7liWCNX2F8NvYjQp2wtInsZxnMlypdw0FtAOLxtvvkO+GSRRbmNi8m/5y42PQJYCQ==} + deprecated: This version has been deprecated and is no longer supported or maintained + + '@intervolga/optimize-cssnano-plugin@1.0.6': + resolution: {integrity: sha512-zN69TnSr0viRSU6cEDIcuPcP67QcpQ6uHACg58FiN9PDrU6SLyGW3MR4tiISbYxy1kDWAVPwD+XwQTWE5cigAA==} + peerDependencies: + webpack: ^4.0.0 + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@leichtgewicht/ip-codec@2.0.5': + resolution: {integrity: sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==} + + '@mrmlnc/readdir-enhanced@2.2.1': + resolution: {integrity: sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==} + engines: {node: '>=4'} + + '@node-ipc/js-queue@2.0.3': + resolution: {integrity: sha512-fL1wpr8hhD5gT2dA1qifeVaoDFlQR5es8tFuKqjHX+kdOtdNHnxkVZbtIrR2rxnMFvehkjaZRNV2H/gPXlb0hw==} + engines: {node: '>=1.0.0'} + + '@nodelib/fs.stat@1.1.3': + resolution: {integrity: sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==} + engines: {node: '>= 6'} + + '@npmcli/fs@1.1.1': + resolution: {integrity: sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==} + + '@npmcli/move-file@1.1.2': + resolution: {integrity: sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==} + engines: {node: '>=10'} + deprecated: This functionality has been moved to @npmcli/fs + + '@riophae/vue-treeselect@0.4.0': + resolution: {integrity: sha512-J4atYmBqXQmiPFK/0B5sXKjtnGc21mBJEiyKIDZwk0Q9XuynVFX6IJ4EpaLmUgL5Tve7HAS7wkiGGSti6Uaxcg==} + peerDependencies: + vue: ^2.2.0 + + '@soda/friendly-errors-webpack-plugin@1.8.1': + resolution: {integrity: sha512-h2ooWqP8XuFqTXT+NyAFbrArzfQA7R6HTezADrvD9Re8fxMLTPPniLdqVTdDaO0eIoLaAwKT+d6w+5GeTk7Vbg==} + engines: {node: '>=8.0.0'} + peerDependencies: + webpack: ^4.0.0 || ^5.0.0 + + '@soda/get-current-script@1.0.2': + resolution: {integrity: sha512-T7VNNlYVM1SgQ+VsMYhnDkcGmWhQdL0bDyGm5TlQ3GBXnJscEClUUOKduWTmm2zCnvNLC1hc3JpuXjs/nFOc5w==} + + '@types/glob@7.2.0': + resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/minimatch@6.0.0': + resolution: {integrity: sha512-zmPitbQ8+6zNutpwgcQuLcsEpn/Cj54Kbn7L5pX0Os5kdWplB7xPgEh/g+SWOB/qmows2gpuCaPyduq8ZZRnxA==} + deprecated: This is a stub types definition. minimatch provides its own type definitions, so you do not need this installed. + + '@types/node@25.6.0': + resolution: {integrity: sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ==} + + '@types/normalize-package-data@2.4.4': + resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} + + '@types/parse-json@4.0.2': + resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} + + '@types/q@1.5.8': + resolution: {integrity: sha512-hroOstUScF6zhIi+5+x0dzqrHA1EJi+Irri6b1fxolMTqqHIV/Cg77EtnQcZqZCu8hR3mX2BzIxN4/GzI68Kfw==} + + '@vue/babel-helper-vue-jsx-merge-props@1.4.0': + resolution: {integrity: sha512-JkqXfCkUDp4PIlFdDQ0TdXoIejMtTHP67/pvxlgeY+u5k3LEdKuWZ3LK6xkxo52uDoABIVyRwqVkfLQJhk7VBA==} + + '@vue/babel-helper-vue-transform-on@1.5.0': + resolution: {integrity: sha512-0dAYkerNhhHutHZ34JtTl2czVQHUNWv6xEbkdF5W+Yrv5pCWsqjeORdOgbtW2I9gWlt+wBmVn+ttqN9ZxR5tzA==} + + '@vue/babel-plugin-jsx@1.5.0': + resolution: {integrity: sha512-mneBhw1oOqCd2247O0Yw/mRwC9jIGACAJUlawkmMBiNmL4dGA2eMzuNZVNqOUfYTa6vqmND4CtOPzmEEEqLKFw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + peerDependenciesMeta: + '@babel/core': + optional: true + + '@vue/babel-plugin-resolve-type@1.5.0': + resolution: {integrity: sha512-Wm/60o+53JwJODm4Knz47dxJnLDJ9FnKnGZJbUUf8nQRAtt6P+undLUAVU3Ha33LxOJe6IPoifRQ6F/0RrU31w==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@vue/babel-plugin-transform-vue-jsx@1.4.0': + resolution: {integrity: sha512-Fmastxw4MMx0vlgLS4XBX0XiBbUFzoMGeVXuMV08wyOfXdikAFqBTuYPR0tlk+XskL19EzHc39SgjrPGY23JnA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@vue/babel-preset-app@4.5.19': + resolution: {integrity: sha512-VCNRiAt2P/bLo09rYt3DLe6xXUMlhJwrvU18Ddd/lYJgC7s8+wvhgYs+MTx4OiAXdu58drGwSBO9SPx7C6J82Q==} + peerDependencies: + '@babel/core': '*' + core-js: ^3 + vue: ^2 || ^3.0.0-0 + peerDependenciesMeta: + core-js: + optional: true + vue: + optional: true + + '@vue/babel-preset-jsx@1.4.0': + resolution: {integrity: sha512-QmfRpssBOPZWL5xw7fOuHNifCQcNQC1PrOo/4fu6xlhlKJJKSA3HqX92Nvgyx8fqHZTUGMPHmFA+IDqwXlqkSA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + vue: '*' + peerDependenciesMeta: + vue: + optional: true + + '@vue/babel-sugar-composition-api-inject-h@1.4.0': + resolution: {integrity: sha512-VQq6zEddJHctnG4w3TfmlVp5FzDavUSut/DwR0xVoe/mJKXyMcsIibL42wPntozITEoY90aBV0/1d2KjxHU52g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@vue/babel-sugar-composition-api-render-instance@1.4.0': + resolution: {integrity: sha512-6ZDAzcxvy7VcnCjNdHJ59mwK02ZFuP5CnucloidqlZwVQv5CQLijc3lGpR7MD3TWFi78J7+a8J56YxbCtHgT9Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@vue/babel-sugar-functional-vue@1.4.0': + resolution: {integrity: sha512-lTEB4WUFNzYt2In6JsoF9sAYVTo84wC4e+PoZWSgM6FUtqRJz7wMylaEhSRgG71YF+wfLD6cc9nqVeXN2rwBvw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@vue/babel-sugar-inject-h@1.4.0': + resolution: {integrity: sha512-muwWrPKli77uO2fFM7eA3G1lAGnERuSz2NgAxuOLzrsTlQl8W4G+wwbM4nB6iewlKbwKRae3nL03UaF5ffAPMA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@vue/babel-sugar-v-model@1.4.0': + resolution: {integrity: sha512-0t4HGgXb7WHYLBciZzN5s0Hzqan4Ue+p/3FdQdcaHAb7s5D9WZFGoSxEZHrR1TFVZlAPu1bejTKGeAzaaG3NCQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@vue/babel-sugar-v-on@1.4.0': + resolution: {integrity: sha512-m+zud4wKLzSKgQrWwhqRObWzmTuyzl6vOP7024lrpeJM4x2UhQtRDLgYjXAw9xBXjCwS0pP9kXjg91F9ZNo9JA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@vue/cli-overlay@4.5.19': + resolution: {integrity: sha512-GdxvNSmOw7NHIazCO8gTK+xZbaOmScTtxj6eHVeMbYpDYVPJ+th3VMLWNpw/b6uOjwzzcyKlA5dRQ1DAb+gF/g==} + + '@vue/cli-plugin-babel@4.4.6': + resolution: {integrity: sha512-9cX9mN+4DIbcqw3rV6UBOA0t5zikIkrBLQloUzsOBOu5Xb7/UoD7inInFj7bnyHUflr5LqbdWJ+etCQcWAIIXA==} + peerDependencies: + '@vue/cli-service': ^3.0.0 || ^4.0.0-0 + + '@vue/cli-plugin-eslint@4.4.6': + resolution: {integrity: sha512-3a9rVpOKPQsDgAlRkhmBMHboGobivG/47BbQGE66Z8YJxrgF/AWikP3Jy67SmxtszRkyiWfw4aJFRV9r3MzffQ==} + peerDependencies: + '@vue/cli-service': ^3.0.0 || ^4.0.0-0 + eslint: '>= 1.6.0' + + '@vue/cli-plugin-router@4.5.19': + resolution: {integrity: sha512-3icGzH1IbVYmMMsOwYa0lal/gtvZLebFXdE5hcQJo2mnTwngXGMTyYAzL56EgHBPjbMmRpyj6Iw9k4aVInVX6A==} + peerDependencies: + '@vue/cli-service': ^3.0.0 || ^4.0.0-0 + + '@vue/cli-plugin-vuex@4.5.19': + resolution: {integrity: sha512-DUmfdkG3pCdkP7Iznd87RfE9Qm42mgp2hcrNcYQYSru1W1gX2dG/JcW8bxmeGSa06lsxi9LEIc/QD1yPajSCZw==} + peerDependencies: + '@vue/cli-service': ^3.0.0 || ^4.0.0-0 + + '@vue/cli-service@4.4.6': + resolution: {integrity: sha512-k5OFGh2NnvRymCyq9DfBiNJvECUuun3pl5KMm3557IZyA5E5csv+RHoSW3dX8HHe0zXq18g52VswP1llvR9POw==} + engines: {node: '>=8'} + hasBin: true + peerDependencies: + less-loader: '*' + pug-plain-loader: '*' + raw-loader: '*' + sass-loader: '*' + stylus-loader: '*' + vue-template-compiler: ^2.0.0 + peerDependenciesMeta: + less-loader: + optional: true + pug-plain-loader: + optional: true + raw-loader: + optional: true + sass-loader: + optional: true + stylus-loader: + optional: true + vue-template-compiler: + optional: true + + '@vue/cli-shared-utils@4.5.19': + resolution: {integrity: sha512-JYpdsrC/d9elerKxbEUtmSSU6QRM60rirVubOewECHkBHj+tLNznWq/EhCjswywtePyLaMUK25eTqnTSZlEE+g==} + + '@vue/compiler-core@3.5.33': + resolution: {integrity: sha512-3PZLQwFw4Za3TC8t0FvTy3wI16Kt+pmwcgNZca4Pj9iWL2E72a/gZlpBtAJvEdDMdCxdG/qq0C7PN0bsJuv0Rw==} + + '@vue/compiler-dom@3.5.33': + resolution: {integrity: sha512-PXq0yrfCLzzL07rbXO4awtXY1Z06LG2eu6Adg3RJFa/j3Cii217XxxLXG22N330gw7GmALCY0Z8RgXEviwgpjA==} + + '@vue/compiler-sfc@3.5.33': + resolution: {integrity: sha512-UTUvRO9cY+rROrx/pvN9P5Z7FgA6QGfokUCfhQE4EnmUj3rVnK+CHI0LsEO1pg+I7//iRYMUfcNcCPe7tg0CoA==} + + '@vue/compiler-ssr@3.5.33': + resolution: {integrity: sha512-IErjYdnj1qIupG5xxiVIYiiRvDhGWV4zuh/RCrwfYpuL+HWQzeU6lCk/nF9r7olWMnjKxCAkOctT2qFWFkzb1A==} + + '@vue/component-compiler-utils@3.3.0': + resolution: {integrity: sha512-97sfH2mYNU+2PzGrmK2haqffDpVASuib9/w2/noxiFi31Z54hW+q3izKQXXQZSNhtiUpAI36uSuYepeBe4wpHQ==} + + '@vue/preload-webpack-plugin@1.1.2': + resolution: {integrity: sha512-LIZMuJk38pk9U9Ur4YzHjlIyMuxPlACdBIHH9/nGYVTsaGKOSnSuELiE8vS9wa+dJpIYspYUOqk+L1Q4pgHQHQ==} + engines: {node: '>=6.0.0'} + peerDependencies: + html-webpack-plugin: '>=2.26.0' + webpack: '>=4.0.0' + + '@vue/shared@3.5.33': + resolution: {integrity: sha512-5vR2QIlmaLG77Ygd4pMP6+SGQ5yox9VhtnbDWTy9DzMzdmeLxZ1QqxrywEZ9sa1AVubfIJyaCG3ytyWU81ufcQ==} + + '@vue/web-component-wrapper@1.3.0': + resolution: {integrity: sha512-Iu8Tbg3f+emIIMmI2ycSI8QcEuAUgPTgHwesDU1eKMLE4YC/c/sFbGc70QgMq31ijRftV0R7vCm9co6rldCeOA==} + + '@webassemblyjs/ast@1.9.0': + resolution: {integrity: sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==} + + '@webassemblyjs/floating-point-hex-parser@1.9.0': + resolution: {integrity: sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==} + + '@webassemblyjs/helper-api-error@1.9.0': + resolution: {integrity: sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==} + + '@webassemblyjs/helper-buffer@1.9.0': + resolution: {integrity: sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==} + + '@webassemblyjs/helper-code-frame@1.9.0': + resolution: {integrity: sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==} + + '@webassemblyjs/helper-fsm@1.9.0': + resolution: {integrity: sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==} + + '@webassemblyjs/helper-module-context@1.9.0': + resolution: {integrity: sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==} + + '@webassemblyjs/helper-wasm-bytecode@1.9.0': + resolution: {integrity: sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==} + + '@webassemblyjs/helper-wasm-section@1.9.0': + resolution: {integrity: sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==} + + '@webassemblyjs/ieee754@1.9.0': + resolution: {integrity: sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==} + + '@webassemblyjs/leb128@1.9.0': + resolution: {integrity: sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==} + + '@webassemblyjs/utf8@1.9.0': + resolution: {integrity: sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==} + + '@webassemblyjs/wasm-edit@1.9.0': + resolution: {integrity: sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==} + + '@webassemblyjs/wasm-gen@1.9.0': + resolution: {integrity: sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==} + + '@webassemblyjs/wasm-opt@1.9.0': + resolution: {integrity: sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==} + + '@webassemblyjs/wasm-parser@1.9.0': + resolution: {integrity: sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==} + + '@webassemblyjs/wast-parser@1.9.0': + resolution: {integrity: sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==} + + '@webassemblyjs/wast-printer@1.9.0': + resolution: {integrity: sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==} + + '@xtuc/ieee754@1.2.0': + resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} + + '@xtuc/long@4.2.2': + resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} + + abbrev@1.1.1: + resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} + + accepts@1.3.8: + resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} + engines: {node: '>= 0.6'} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn-walk@7.2.0: + resolution: {integrity: sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==} + engines: {node: '>=0.4.0'} + + acorn@6.4.2: + resolution: {integrity: sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==} + engines: {node: '>=0.4.0'} + hasBin: true + + acorn@7.4.1: + resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} + engines: {node: '>=0.4.0'} + hasBin: true + + acorn@8.16.0: + resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} + engines: {node: '>=0.4.0'} + hasBin: true + + address@1.2.2: + resolution: {integrity: sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==} + engines: {node: '>= 10.0.0'} + + aggregate-error@3.1.0: + resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} + engines: {node: '>=8'} + + ajv-errors@1.0.1: + resolution: {integrity: sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==} + peerDependencies: + ajv: '>=5.0.0' + + ajv-keywords@3.5.2: + resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} + peerDependencies: + ajv: ^6.9.1 + + ajv@6.15.0: + resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==} + + alphanum-sort@1.0.2: + resolution: {integrity: sha512-0FcBfdcmaumGPQ0qPn7Q5qTgz/ooXgIyp1rf8ik5bGX8mpE2YHjC0P/eyQvxu1GURYQgq9ozf2mteQ5ZD9YiyQ==} + + ansi-colors@3.2.4: + resolution: {integrity: sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==} + engines: {node: '>=6'} + + ansi-colors@4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} + engines: {node: '>=6'} + + ansi-escapes@4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + + ansi-html-community@0.0.8: + resolution: {integrity: sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==} + engines: {'0': node >= 0.8.0} + hasBin: true + + ansi-regex@2.1.1: + resolution: {integrity: sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==} + engines: {node: '>=0.10.0'} + + ansi-regex@4.1.1: + resolution: {integrity: sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==} + engines: {node: '>=6'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-styles@2.2.1: + resolution: {integrity: sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==} + engines: {node: '>=0.10.0'} + + ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + + anymatch@2.0.0: + resolution: {integrity: sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + aproba@1.2.0: + resolution: {integrity: sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==} + + arch@2.2.0: + resolution: {integrity: sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==} + + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + + arr-diff@4.0.0: + resolution: {integrity: sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==} + engines: {node: '>=0.10.0'} + + arr-flatten@1.1.0: + resolution: {integrity: sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==} + engines: {node: '>=0.10.0'} + + arr-union@3.1.0: + resolution: {integrity: sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==} + engines: {node: '>=0.10.0'} + + array-buffer-byte-length@1.0.2: + resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} + engines: {node: '>= 0.4'} + + array-flatten@1.1.1: + resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} + + array-flatten@2.1.2: + resolution: {integrity: sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==} + + array-union@1.0.2: + resolution: {integrity: sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==} + engines: {node: '>=0.10.0'} + + array-uniq@1.0.3: + resolution: {integrity: sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==} + engines: {node: '>=0.10.0'} + + array-unique@0.3.2: + resolution: {integrity: sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==} + engines: {node: '>=0.10.0'} + + array.prototype.reduce@1.0.8: + resolution: {integrity: sha512-DwuEqgXFBwbmZSRqt3BpQigWNUoqw9Ml2dTWdF3B2zQlQX4OeUE0zyuzX0fX0IbTvjdkZbcBTU3idgpO78qkTw==} + engines: {node: '>= 0.4'} + + arraybuffer.prototype.slice@1.0.4: + resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} + engines: {node: '>= 0.4'} + + asn1.js@4.10.1: + resolution: {integrity: sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==} + + asn1@0.2.6: + resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} + + assert-plus@1.0.0: + resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==} + engines: {node: '>=0.8'} + + assert@1.5.1: + resolution: {integrity: sha512-zzw1uCAgLbsKwBfFc8CX78DDg+xZeBksSO3vwVIDDN5i94eOrPsSSyiVhmsSABFDM/OcpE2aagCat9dnWQLG1A==} + + assign-symbols@1.0.0: + resolution: {integrity: sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==} + engines: {node: '>=0.10.0'} + + astral-regex@1.0.0: + resolution: {integrity: sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==} + engines: {node: '>=4'} + + astral-regex@2.0.0: + resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} + engines: {node: '>=8'} + + async-each@1.0.6: + resolution: {integrity: sha512-c646jH1avxr+aVpndVMeAfYw7wAa6idufrlN3LPA4PmKS0QEGp6PIC9nwz0WQkkvBGAMEki3pFdtxaF39J9vvg==} + + async-function@1.0.0: + resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} + engines: {node: '>= 0.4'} + + async-limiter@1.0.1: + resolution: {integrity: sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==} + + async-validator@1.8.5: + resolution: {integrity: sha512-tXBM+1m056MAX0E8TL2iCjg8WvSyXu0Zc8LNtYqrVeyoL3+esHRZ4SieE9fKQyyU09uONjnMEjrNBMqT0mbvmA==} + + async@3.2.6: + resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + atob@2.1.2: + resolution: {integrity: sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==} + engines: {node: '>= 4.5.0'} + hasBin: true + + autoprefixer@9.8.8: + resolution: {integrity: sha512-eM9d/swFopRt5gdJ7jrpCwgvEMIayITpojhkkSMRsFHYuH5bkSQ4p/9qTEHtmNudUZh22Tehu7I6CxAW0IXTKA==} + hasBin: true + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + aws-sign2@0.7.0: + resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==} + + aws4@1.13.2: + resolution: {integrity: sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==} + + axios@0.28.1: + resolution: {integrity: sha512-iUcGA5a7p0mVb4Gm/sy+FSECNkPFT4y7wt6OM/CDpO/OnNCvSs3PoMG8ibrC9jRoGYU0gUK5pXVC4NPXq6lHRQ==} + + babel-eslint@10.1.0: + resolution: {integrity: sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==} + engines: {node: '>=6'} + deprecated: babel-eslint is now @babel/eslint-parser. This package will no longer receive updates. + peerDependencies: + eslint: '>= 4.12.1' + + babel-helper-vue-jsx-merge-props@2.0.3: + resolution: {integrity: sha512-gsLiKK7Qrb7zYJNgiXKpXblxbV5ffSwR0f5whkPAaBAR4fhi6bwRZxX9wBlIc5M/v8CCkXUbXZL4N/nSE97cqg==} + + babel-loader@8.4.1: + resolution: {integrity: sha512-nXzRChX+Z1GoE6yWavBQg6jDslyFF3SDjl2paADuoQtQW10JqShJt62R6eJQ5m/pjJFDT8xgKIWSP85OY8eXeA==} + engines: {node: '>= 8.9'} + peerDependencies: + '@babel/core': ^7.0.0 + webpack: '>=2' + + babel-plugin-dynamic-import-node@2.3.3: + resolution: {integrity: sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==} + + babel-plugin-polyfill-corejs2@0.4.17: + resolution: {integrity: sha512-aTyf30K/rqAsNwN76zYrdtx8obu0E4KoUME29B1xj+B3WxgvWkp943vYQ+z8Mv3lw9xHXMHpvSPOBxzAkIa94w==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + babel-plugin-polyfill-corejs3@0.13.0: + resolution: {integrity: sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + babel-plugin-polyfill-corejs3@0.14.2: + resolution: {integrity: sha512-coWpDLJ410R781Npmn/SIBZEsAetR4xVi0SxLMXPaMO4lSf1MwnkGYMtkFxew0Dn8B3/CpbpYxN0JCgg8mn67g==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + babel-plugin-polyfill-regenerator@0.6.8: + resolution: {integrity: sha512-M762rNHfSF1EV3SLtnCJXFoQbbIIz0OyRwnCmV0KPC7qosSfCO0QLTSuJX3ayAebubhE6oYBAYPrBA5ljowaZg==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + babel-runtime@6.26.0: + resolution: {integrity: sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + balanced-match@4.0.4: + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} + engines: {node: 18 || 20 || >=22} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + base@0.11.2: + resolution: {integrity: sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==} + engines: {node: '>=0.10.0'} + + baseline-browser-mapping@2.10.22: + resolution: {integrity: sha512-6qruVrb5rse6WylFkU0FhBKKGuecWseqdpQfhkawn6ztyk2QlfwSRjsDxMCLJrkfmfN21qvhl9ABgaMeRkuwww==} + engines: {node: '>=6.0.0'} + hasBin: true + + batch@0.6.1: + resolution: {integrity: sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==} + + bcrypt-pbkdf@1.0.2: + resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} + + bfj@6.1.2: + resolution: {integrity: sha512-BmBJa4Lip6BPRINSZ0BPEIfB1wUY/9rwbwvIHQA1KjX9om29B6id0wnWXq7m3bn5JrUVjeOTnVuhPT1FiHwPGw==} + engines: {node: '>= 6.0.0'} + + big.js@3.2.0: + resolution: {integrity: sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==} + + big.js@5.2.2: + resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==} + + binary-extensions@1.13.1: + resolution: {integrity: sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==} + engines: {node: '>=0.10.0'} + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + bindings@1.5.0: + resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + + bluebird@3.7.2: + resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} + + bn.js@4.12.3: + resolution: {integrity: sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g==} + + bn.js@5.2.3: + resolution: {integrity: sha512-EAcmnPkxpntVL+DS7bO1zhcZNvCkxqtkd0ZY53h06GNQ3DEkkGZ/gKgmDv6DdZQGj9BgfSPKtJJ7Dp1GPP8f7w==} + + body-parser@1.20.5: + resolution: {integrity: sha512-3grm+/2tUOvu2cjJkvsIxrv/wVpfXQW4PsQHYm7yk4vfpu7Ekl6nEsYBoJUL6qDwZUx8wUhQ8tR2qz+ad9c9OA==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + bonjour@3.5.1: + resolution: {integrity: sha512-xONzj4PfpPJw6xSqCcT2SmQkBOXpUINUz3o3qXcWJwYlXbkZNcNaUae0o5lle7tKt4HHV6dTgkIRhAXZ3nBMsQ==} + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + + brace-expansion@1.1.14: + resolution: {integrity: sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==} + + brace-expansion@5.0.5: + resolution: {integrity: sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==} + engines: {node: 18 || 20 || >=22} + + braces@2.3.2: + resolution: {integrity: sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==} + engines: {node: '>=0.10.0'} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + brorand@1.1.0: + resolution: {integrity: sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==} + + browserify-aes@1.2.0: + resolution: {integrity: sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==} + + browserify-cipher@1.0.1: + resolution: {integrity: sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==} + + browserify-des@1.0.2: + resolution: {integrity: sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==} + + browserify-rsa@4.1.1: + resolution: {integrity: sha512-YBjSAiTqM04ZVei6sXighu679a3SqWORA3qZTEqZImnlkDIFtKc6pNutpjyZ8RJTjQtuYfeetkxM11GwoYXMIQ==} + engines: {node: '>= 0.10'} + + browserify-sign@4.2.5: + resolution: {integrity: sha512-C2AUdAJg6rlM2W5QMp2Q4KGQMVBwR1lIimTsUnutJ8bMpW5B52pGpR2gEnNBNwijumDo5FojQ0L9JrXA8m4YEw==} + engines: {node: '>= 0.10'} + + browserify-zlib@0.2.0: + resolution: {integrity: sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==} + + browserslist@4.28.2: + resolution: {integrity: sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + buffer-indexof@1.1.1: + resolution: {integrity: sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==} + + buffer-json@2.0.0: + resolution: {integrity: sha512-+jjPFVqyfF1esi9fvfUs3NqM0pH1ziZ36VP4hmA/y/Ssfo/5w5xHKfTw9BwQjoJ1w/oVtpLomqwUHKdefGyuHw==} + + buffer-xor@1.0.3: + resolution: {integrity: sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==} + + buffer@4.9.2: + resolution: {integrity: sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==} + + builtin-status-codes@3.0.0: + resolution: {integrity: sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==} + + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + cacache@12.0.4: + resolution: {integrity: sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==} + + cacache@13.0.1: + resolution: {integrity: sha512-5ZvAxd05HDDU+y9BVvcqYu2LLXmPnQ0hW62h32g4xBTgL/MppR4/04NHfj/ycM2y6lmTnbw6HVi+1eN0Psba6w==} + engines: {node: '>= 8'} + + cacache@15.3.0: + resolution: {integrity: sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==} + engines: {node: '>= 10'} + + cache-base@1.0.1: + resolution: {integrity: sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==} + engines: {node: '>=0.10.0'} + + cache-loader@4.1.0: + resolution: {integrity: sha512-ftOayxve0PwKzBF/GLsZNC9fJBXl8lkZE3TOsjkboHfVHVkL39iUEs1FO07A33mizmci5Dudt38UZrrYXDtbhw==} + engines: {node: '>= 8.9.0'} + peerDependencies: + webpack: ^4.0.0 + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bind@1.0.9: + resolution: {integrity: sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + call-me-maybe@1.0.2: + resolution: {integrity: sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==} + + caller-callsite@2.0.0: + resolution: {integrity: sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==} + engines: {node: '>=4'} + + caller-path@2.0.0: + resolution: {integrity: sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==} + engines: {node: '>=4'} + + callsites@2.0.0: + resolution: {integrity: sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==} + engines: {node: '>=4'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + camel-case@3.0.0: + resolution: {integrity: sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==} + + camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + + caniuse-api@3.0.0: + resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} + + caniuse-lite@1.0.30001790: + resolution: {integrity: sha512-bOoxfJPyYo+ds6W0YfptaCWbFnJYjh2Y1Eow5lRv+vI2u8ganPZqNm1JwNh0t2ELQCqIWg4B3dWEusgAmsoyOw==} + + case-sensitive-paths-webpack-plugin@2.4.0: + resolution: {integrity: sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==} + engines: {node: '>=4'} + + caseless@0.12.0: + resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} + + chalk@1.1.3: + resolution: {integrity: sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==} + engines: {node: '>=0.10.0'} + + chalk@2.3.0: + resolution: {integrity: sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==} + engines: {node: '>=4'} + + chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + + chalk@3.0.0: + resolution: {integrity: sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==} + engines: {node: '>=8'} + + chalk@4.1.0: + resolution: {integrity: sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==} + engines: {node: '>=10'} + + chardet@0.7.0: + resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} + + check-types@8.0.3: + resolution: {integrity: sha512-YpeKZngUmG65rLudJ4taU7VLkOCTMhNl/u4ctNC56LQS/zJTyNH0Lrtwm1tfTsbLlwvlfsA2d1c8vCf/Kh2KwQ==} + + chokidar@2.1.8: + resolution: {integrity: sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + + chownr@1.1.4: + resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} + + chownr@2.0.0: + resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} + engines: {node: '>=10'} + + chrome-trace-event@1.0.4: + resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==} + engines: {node: '>=6.0'} + + ci-info@1.6.0: + resolution: {integrity: sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==} + + cipher-base@1.0.7: + resolution: {integrity: sha512-Mz9QMT5fJe7bKI7MH31UilT5cEK5EHHRCccw/YRFsRY47AuNgaV6HY3rscp0/I4Q+tTW/5zoqpSeRRI54TkDWA==} + engines: {node: '>= 0.10'} + + class-utils@0.3.6: + resolution: {integrity: sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==} + engines: {node: '>=0.10.0'} + + clean-css@4.2.4: + resolution: {integrity: sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==} + engines: {node: '>= 4.0'} + + clean-stack@2.2.0: + resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} + engines: {node: '>=6'} + + cli-cursor@2.1.0: + resolution: {integrity: sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==} + engines: {node: '>=4'} + + cli-cursor@3.1.0: + resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} + engines: {node: '>=8'} + + cli-highlight@2.1.11: + resolution: {integrity: sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==} + engines: {node: '>=8.0.0', npm: '>=5.0.0'} + hasBin: true + + cli-spinners@2.9.2: + resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} + engines: {node: '>=6'} + + cli-truncate@2.1.0: + resolution: {integrity: sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==} + engines: {node: '>=8'} + + cli-width@3.0.0: + resolution: {integrity: sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==} + engines: {node: '>= 10'} + + clipboard@2.0.8: + resolution: {integrity: sha512-Y6WO0unAIQp5bLmk1zdThRhgJt/x3ks6f30s3oE3H1mgIEU33XyQjEf8gsf6DxC7NPX8Y1SsNWjUjL/ywLnnbQ==} + + clipboardy@2.3.0: + resolution: {integrity: sha512-mKhiIL2DrQIsuXMgBgnfEHOZOryC7kY7YO//TN6c63wlEm3NG5tz+YgY5rVi29KCmq/QQjKYvM7a19+MDOTHOQ==} + engines: {node: '>=8'} + + cliui@5.0.0: + resolution: {integrity: sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==} + + cliui@6.0.0: + resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} + + cliui@7.0.4: + resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} + + clone@1.0.4: + resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} + engines: {node: '>=0.8'} + + clone@2.1.2: + resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} + engines: {node: '>=0.8'} + + coa@2.0.2: + resolution: {integrity: sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==} + engines: {node: '>= 4.0'} + + collection-visit@1.0.0: + resolution: {integrity: sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==} + engines: {node: '>=0.10.0'} + + color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + + color@3.2.1: + resolution: {integrity: sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==} + + colorette@2.0.20: + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + commander@2.17.1: + resolution: {integrity: sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==} + + commander@2.19.0: + resolution: {integrity: sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==} + + commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + + commander@6.2.1: + resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==} + engines: {node: '>= 6'} + + commondir@1.0.1: + resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} + + component-emitter@1.3.1: + resolution: {integrity: sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==} + + compressible@2.0.18: + resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} + engines: {node: '>= 0.6'} + + compression-webpack-plugin@6.1.2: + resolution: {integrity: sha512-z6xtgKP3Uds2lyrkx2PGwrE9FZT8raHTC3ImFrY3e0faAfSfVIV63JmR+sfk5pf4OhUj3E4XdjZBCKpjYWIw6Q==} + engines: {node: '>= 10.13.0'} + peerDependencies: + webpack: ^4.0.0 || ^5.0.0 + + compression@1.8.1: + resolution: {integrity: sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==} + engines: {node: '>= 0.8.0'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + concat-stream@1.6.2: + resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==} + engines: {'0': node >= 0.8} + + config-chain@1.1.13: + resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==} + + connect-history-api-fallback@1.6.0: + resolution: {integrity: sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==} + engines: {node: '>=0.8'} + + connect@3.6.6: + resolution: {integrity: sha512-OO7axMmPpu/2XuX1+2Yrg0ddju31B6xLZMWkJ5rYBu4YRmRVlOjvlY6kw2FJKiAzyxGwnrDUAG4s1Pf0sbBMCQ==} + engines: {node: '>= 0.10.0'} + + console-browserify@1.2.0: + resolution: {integrity: sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==} + + consolidate@0.15.1: + resolution: {integrity: sha512-DW46nrsMJgy9kqAbPt5rKaCr7uFtpo4mSUvLHIUbJEjm0vo+aY5QLwBUq3FK4tRnJr/X0Psc0C4jf/h+HtXSMw==} + engines: {node: '>= 0.10.0'} + deprecated: Please upgrade to consolidate v1.0.0+ as it has been modernized with several long-awaited fixes implemented. Maintenance is supported by Forward Email at https://forwardemail.net ; follow/watch https://github.com/ladjs/consolidate for updates and release changelog + peerDependencies: + arc-templates: ^0.5.3 + atpl: '>=0.7.6' + babel-core: ^6.26.3 + bracket-template: ^1.1.5 + coffee-script: ^1.12.7 + dot: ^1.1.3 + dust: ^0.3.0 + dustjs-helpers: ^1.7.4 + dustjs-linkedin: ^2.7.5 + eco: ^1.1.0-rc-3 + ect: ^0.5.9 + ejs: ^3.1.5 + haml-coffee: ^1.14.1 + hamlet: ^0.3.3 + hamljs: ^0.6.2 + handlebars: ^4.7.6 + hogan.js: ^3.0.2 + htmling: ^0.0.8 + jade: ^1.11.0 + jazz: ^0.0.18 + jqtpl: ~1.1.0 + just: ^0.1.8 + liquid-node: ^3.0.1 + liquor: ^0.0.5 + lodash: ^4.17.20 + marko: ^3.14.4 + mote: ^0.2.0 + mustache: ^3.0.0 + nunjucks: ^3.2.2 + plates: ~0.4.11 + pug: ^3.0.0 + qejs: ^3.0.5 + ractive: ^1.3.12 + razor-tmpl: ^1.3.1 + react: ^16.13.1 + react-dom: ^16.13.1 + slm: ^2.0.0 + squirrelly: ^5.1.0 + swig: ^1.4.2 + swig-templates: ^2.0.3 + teacup: ^2.0.0 + templayed: '>=0.2.3' + then-jade: '*' + then-pug: '*' + tinyliquid: ^0.2.34 + toffee: ^0.3.6 + twig: ^1.15.2 + twing: ^5.0.2 + underscore: ^1.11.0 + vash: ^0.13.0 + velocityjs: ^2.0.1 + walrus: ^0.10.1 + whiskers: ^0.4.0 + peerDependenciesMeta: + arc-templates: + optional: true + atpl: + optional: true + babel-core: + optional: true + bracket-template: + optional: true + coffee-script: + optional: true + dot: + optional: true + dust: + optional: true + dustjs-helpers: + optional: true + dustjs-linkedin: + optional: true + eco: + optional: true + ect: + optional: true + ejs: + optional: true + haml-coffee: + optional: true + hamlet: + optional: true + hamljs: + optional: true + handlebars: + optional: true + hogan.js: + optional: true + htmling: + optional: true + jade: + optional: true + jazz: + optional: true + jqtpl: + optional: true + just: + optional: true + liquid-node: + optional: true + liquor: + optional: true + lodash: + optional: true + marko: + optional: true + mote: + optional: true + mustache: + optional: true + nunjucks: + optional: true + plates: + optional: true + pug: + optional: true + qejs: + optional: true + ractive: + optional: true + razor-tmpl: + optional: true + react: + optional: true + react-dom: + optional: true + slm: + optional: true + squirrelly: + optional: true + swig: + optional: true + swig-templates: + optional: true + teacup: + optional: true + templayed: + optional: true + then-jade: + optional: true + then-pug: + optional: true + tinyliquid: + optional: true + toffee: + optional: true + twig: + optional: true + twing: + optional: true + underscore: + optional: true + vash: + optional: true + velocityjs: + optional: true + walrus: + optional: true + whiskers: + optional: true + + constants-browserify@1.0.0: + resolution: {integrity: sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==} + + content-disposition@0.5.4: + resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} + engines: {node: '>= 0.6'} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cookie-signature@1.0.7: + resolution: {integrity: sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==} + + cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} + engines: {node: '>= 0.6'} + + copy-concurrently@1.0.5: + resolution: {integrity: sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==} + deprecated: This package is no longer supported. + + copy-descriptor@0.1.1: + resolution: {integrity: sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==} + engines: {node: '>=0.10.0'} + + copy-webpack-plugin@5.1.2: + resolution: {integrity: sha512-Uh7crJAco3AjBvgAy9Z75CjK8IG+gxaErro71THQ+vv/bl4HaQcpkexAY8KVW/T6D2W2IRr+couF/knIRkZMIQ==} + engines: {node: '>= 6.9.0'} + peerDependencies: + webpack: ^4.0.0 || ^5.0.0 + + core-js-compat@3.49.0: + resolution: {integrity: sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==} + + core-js@2.6.12: + resolution: {integrity: sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==} + deprecated: core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js. + + core-js@3.37.1: + resolution: {integrity: sha512-Xn6qmxrQZyB0FFY8E3bgRXei3lWDJHhvI+u0q9TKIYM49G8pAr0FgnnrFRAmsbptZL1yxRADVXn+x5AGsbBfyw==} + + core-util-is@1.0.2: + resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} + + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + + cosmiconfig@5.2.1: + resolution: {integrity: sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==} + engines: {node: '>=4'} + + cosmiconfig@7.1.0: + resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==} + engines: {node: '>=10'} + + create-ecdh@4.0.4: + resolution: {integrity: sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==} + + create-hash@1.2.0: + resolution: {integrity: sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==} + + create-hmac@1.1.7: + resolution: {integrity: sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==} + + cross-spawn@5.1.0: + resolution: {integrity: sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==} + + cross-spawn@6.0.6: + resolution: {integrity: sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==} + engines: {node: '>=4.8'} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + crypto-browserify@3.12.1: + resolution: {integrity: sha512-r4ESw/IlusD17lgQi1O20Fa3qNnsckR126TdUuBgAu7GBYSIPvdNyONd3Zrxh0xCwA4+6w/TDArBPsMvhur+KQ==} + engines: {node: '>= 0.10'} + + css-color-names@0.0.4: + resolution: {integrity: sha512-zj5D7X1U2h2zsXOAM8EyUREBnnts6H+Jm+d1M2DbiQQcUtnqgQsMrdo8JW9R80YFUmIdBZeMu5wvYM7hcgWP/Q==} + + css-declaration-sorter@4.0.1: + resolution: {integrity: sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==} + engines: {node: '>4'} + + css-loader@3.6.0: + resolution: {integrity: sha512-M5lSukoWi1If8dhQAUCvj4H8vUt3vOnwbQBH9DdTm/s4Ym2B/3dPMtYZeJmq7Q3S3Pa+I94DcZ7pc9bP14cWIQ==} + engines: {node: '>= 8.9.0'} + peerDependencies: + webpack: ^4.0.0 || ^5.0.0 + + css-select-base-adapter@0.1.1: + resolution: {integrity: sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==} + + css-select@2.1.0: + resolution: {integrity: sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==} + + css-select@4.3.0: + resolution: {integrity: sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==} + + css-tree@1.0.0-alpha.37: + resolution: {integrity: sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==} + engines: {node: '>=8.0.0'} + + css-tree@1.1.3: + resolution: {integrity: sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==} + engines: {node: '>=8.0.0'} + + css-what@3.4.2: + resolution: {integrity: sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==} + engines: {node: '>= 6'} + + css-what@6.2.2: + resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} + engines: {node: '>= 6'} + + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + cssnano-preset-default@4.0.8: + resolution: {integrity: sha512-LdAyHuq+VRyeVREFmuxUZR1TXjQm8QQU/ktoo/x7bz+SdOge1YKc5eMN6pRW7YWBmyq59CqYba1dJ5cUukEjLQ==} + engines: {node: '>=6.9.0'} + + cssnano-util-get-arguments@4.0.0: + resolution: {integrity: sha512-6RIcwmV3/cBMG8Aj5gucQRsJb4vv4I4rn6YjPbVWd5+Pn/fuG+YseGvXGk00XLkoZkaj31QOD7vMUpNPC4FIuw==} + engines: {node: '>=6.9.0'} + + cssnano-util-get-match@4.0.0: + resolution: {integrity: sha512-JPMZ1TSMRUPVIqEalIBNoBtAYbi8okvcFns4O0YIhcdGebeYZK7dMyHJiQ6GqNBA9kE0Hym4Aqym5rPdsV/4Cw==} + engines: {node: '>=6.9.0'} + + cssnano-util-raw-cache@4.0.1: + resolution: {integrity: sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==} + engines: {node: '>=6.9.0'} + + cssnano-util-same-parent@4.0.1: + resolution: {integrity: sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==} + engines: {node: '>=6.9.0'} + + cssnano@4.1.11: + resolution: {integrity: sha512-6gZm2htn7xIPJOHY824ERgj8cNPgPxyCSnkXc4v7YvNW+TdVfzgngHcEhy/8D11kUWRUMbke+tC+AUcUsnMz2g==} + engines: {node: '>=6.9.0'} + + csso@4.2.0: + resolution: {integrity: sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==} + engines: {node: '>=8.0.0'} + + cyclist@1.0.2: + resolution: {integrity: sha512-0sVXIohTfLqVIW3kb/0n6IiWF3Ifj5nm2XaSrLq2DI6fKIGa2fYAZdk917rUneaeLVpYfFcyXE2ft0fe3remsA==} + + dashdash@1.14.1: + resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==} + engines: {node: '>=0.10'} + + data-view-buffer@1.0.2: + resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} + engines: {node: '>= 0.4'} + + data-view-byte-length@1.0.2: + resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} + engines: {node: '>= 0.4'} + + data-view-byte-offset@1.0.1: + resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} + engines: {node: '>= 0.4'} + + de-indent@1.0.2: + resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==} + + debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decamelize@1.2.0: + resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} + engines: {node: '>=0.10.0'} + + decode-uri-component@0.2.2: + resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==} + engines: {node: '>=0.10'} + + dedent@0.7.0: + resolution: {integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==} + + deep-equal@1.1.2: + resolution: {integrity: sha512-5tdhKF6DbU7iIzrIOa1AOUt39ZRm13cmL1cGEh//aqR8x9+tNfbywRf0n5FD/18OKMdo7DNEtrX2t22ZAkI+eg==} + engines: {node: '>= 0.4'} + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + deepmerge@1.3.2: + resolution: {integrity: sha512-qjMjTrk+RKv/sp4RPDpV5CnKhxjFI9p+GkLBOls5A8EEElldYWCWA9zceAkmfd0xIo2aU1nxiaLFoiya2sb6Cg==} + engines: {node: '>=0.10.0'} + + deepmerge@1.5.2: + resolution: {integrity: sha512-95k0GDqvBjZavkuvzx/YqVLv/6YYa17fz6ILMSf7neqQITCPbnfEnQvEgMPNjH4kgobe7+WIL0yJEHku+H3qtQ==} + engines: {node: '>=0.10.0'} + + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + + default-gateway@4.2.0: + resolution: {integrity: sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==} + engines: {node: '>=6'} + + default-gateway@5.0.5: + resolution: {integrity: sha512-z2RnruVmj8hVMmAnEJMTIJNijhKCDiGjbLP+BHJFOT7ld3Bo5qcIBpVYDniqhbMIIf+jZDlkP2MkPXiQy/DBLA==} + engines: {node: ^8.12.0 || >=9.7.0} + + defaults@1.0.4: + resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + + define-property@0.2.5: + resolution: {integrity: sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==} + engines: {node: '>=0.10.0'} + + define-property@1.0.0: + resolution: {integrity: sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==} + engines: {node: '>=0.10.0'} + + define-property@2.0.2: + resolution: {integrity: sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==} + engines: {node: '>=0.10.0'} + + del@4.1.1: + resolution: {integrity: sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==} + engines: {node: '>=6'} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + delegate@3.2.0: + resolution: {integrity: sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==} + + depd@1.1.2: + resolution: {integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==} + engines: {node: '>= 0.6'} + + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + des.js@1.1.0: + resolution: {integrity: sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==} + + destroy@1.2.0: + resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + detect-node@2.1.0: + resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==} + + diffie-hellman@5.0.3: + resolution: {integrity: sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==} + + dir-glob@2.2.2: + resolution: {integrity: sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==} + engines: {node: '>=4'} + + dns-equal@1.0.0: + resolution: {integrity: sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==} + + dns-packet@5.6.1: + resolution: {integrity: sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==} + engines: {node: '>=6'} + + dns-txt@2.0.2: + resolution: {integrity: sha512-Ix5PrWjphuSoUXV/Zv5gaFHjnaJtb02F2+Si3Ht9dyJ87+Z/lMmy+dpNHtTGraNK958ndXq2i+GLkWsWHcKaBQ==} + + doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + + dom-converter@0.2.0: + resolution: {integrity: sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==} + + dom-serializer@0.2.2: + resolution: {integrity: sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==} + + dom-serializer@1.4.1: + resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==} + + domain-browser@1.2.0: + resolution: {integrity: sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==} + engines: {node: '>=0.4', npm: '>=1.2'} + + domelementtype@1.3.1: + resolution: {integrity: sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domhandler@2.4.2: + resolution: {integrity: sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==} + + domhandler@4.3.1: + resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==} + engines: {node: '>= 4'} + + domready@1.0.8: + resolution: {integrity: sha512-uIzsOJUNk+AdGE9a6VDeessoMCzF8RrZvJCX/W8QtyfgdR6Uofn/MvRonih3OtCO79b2VDzDOymuiABrQ4z3XA==} + + domutils@1.7.0: + resolution: {integrity: sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==} + + domutils@2.8.0: + resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==} + + dot-prop@5.3.0: + resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} + engines: {node: '>=8'} + + dotenv-expand@5.1.0: + resolution: {integrity: sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==} + + dotenv@8.6.0: + resolution: {integrity: sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==} + engines: {node: '>=10'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + duplexer@0.1.2: + resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} + + duplexify@3.7.1: + resolution: {integrity: sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==} + + easings-css@1.0.0: + resolution: {integrity: sha512-7Uq7NdazNfVtr0RNmPAys8it0zKCuaqxJStYKEl72D3j4gbvXhhaM7iWNbqhA4C94ygCye6VuyhzBRQC4szeBg==} + + easy-stack@1.0.1: + resolution: {integrity: sha512-wK2sCs4feiiJeFXn3zvY0p41mdU5VUgbgs1rNsc/y5ngFUijdWd+iIN8eoyuZHKB8xN6BL4PdWmzqFmxNg6V2w==} + engines: {node: '>=6.0.0'} + + ecc-jsbn@0.1.2: + resolution: {integrity: sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==} + + echarts@5.4.0: + resolution: {integrity: sha512-uPsO9VRUIKAdFOoH3B0aNg7NRVdN7aM39/OjovjO9MwmWsAkfGyeXJhK+dbRi51iDrQWliXV60/XwLA7kg3z0w==} + + editorconfig@0.15.3: + resolution: {integrity: sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==} + hasBin: true + + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + + ejs@2.7.4: + resolution: {integrity: sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA==} + engines: {node: '>=0.10.0'} + + electron-to-chromium@1.5.344: + resolution: {integrity: sha512-4MxfbmNDm+KPh066EZy+eUnkcDPcZ35wNmOWzFuh/ijvHsve6kbLTLURy88uCNK5FbpN+yk2nQY6BYh1GEt+wg==} + + element-ui@2.15.14: + resolution: {integrity: sha512-2v9fHL0ZGINotOlRIAJD5YuVB8V7WKxrE9Qy7dXhRipa035+kF7WuU/z+tEmLVPBcJ0zt8mOu1DKpWcVzBK8IA==} + peerDependencies: + vue: ^2.5.17 + + elliptic@6.6.1: + resolution: {integrity: sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==} + + emoji-regex@7.0.3: + resolution: {integrity: sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emojis-list@2.1.0: + resolution: {integrity: sha512-knHEZMgs8BB+MInokmNTg/OyPlAddghe1YBgNwJBc5zsJi/uyIcXoSDsL/W9ymOsBoBGdPIHXYJ9+qKFwRwDng==} + engines: {node: '>= 0.10'} + + emojis-list@3.0.0: + resolution: {integrity: sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==} + engines: {node: '>= 4'} + + encodeurl@1.0.2: + resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} + engines: {node: '>= 0.8'} + + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + + end-of-stream@1.4.5: + resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} + + enhanced-resolve@4.5.0: + resolution: {integrity: sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==} + engines: {node: '>=6.9.0'} + + enquirer@2.4.1: + resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} + engines: {node: '>=8.6'} + + entities@1.1.2: + resolution: {integrity: sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==} + + entities@2.2.0: + resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} + + entities@7.0.1: + resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==} + engines: {node: '>=0.12'} + + errno@0.1.8: + resolution: {integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==} + hasBin: true + + error-ex@1.3.4: + resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} + + error-stack-parser@2.1.4: + resolution: {integrity: sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==} + + es-abstract@1.24.2: + resolution: {integrity: sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==} + engines: {node: '>= 0.4'} + + es-array-method-boxes-properly@1.0.0: + resolution: {integrity: sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + + es-to-primitive@1.3.0: + resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} + engines: {node: '>= 0.4'} + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + + eslint-loader@2.2.1: + resolution: {integrity: sha512-RLgV9hoCVsMLvOxCuNjdqOrUqIj9oJg8hF44vzJaYqsAHuY9G2YAeN3joQ9nxP0p5Th9iFSIpKo+SD8KISxXRg==} + deprecated: This loader has been deprecated. Please use eslint-webpack-plugin + peerDependencies: + eslint: '>=1.6.0 <7.0.0' + webpack: '>=2.0.0 <5.0.0' + + eslint-plugin-vue@7.2.0: + resolution: {integrity: sha512-4mt0yIv6rBDNtvis/g22a0ozJ12GfcdEzX77u0ICYjKlxOVtGrKGEvo0cbOObHaKDg9a9kJcoaNodqE4TPfS2A==} + engines: {node: '>=8.10'} + peerDependencies: + eslint: ^6.2.0 || ^7.0.0 + + eslint-scope@4.0.3: + resolution: {integrity: sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==} + engines: {node: '>=4.0.0'} + + eslint-scope@5.1.1: + resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} + engines: {node: '>=8.0.0'} + + eslint-utils@2.1.0: + resolution: {integrity: sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==} + engines: {node: '>=6'} + + eslint-visitor-keys@1.3.0: + resolution: {integrity: sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==} + engines: {node: '>=4'} + + eslint-visitor-keys@2.1.0: + resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==} + engines: {node: '>=10'} + + eslint@7.15.0: + resolution: {integrity: sha512-Vr64xFDT8w30wFll643e7cGrIkPEU50yIiI36OdSIDoSGguIeaLzBo0vpGvzo9RECUqq7htURfwEtKqwytkqzA==} + engines: {node: ^10.12.0 || >=12.0.0} + deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. + hasBin: true + + espree@6.2.1: + resolution: {integrity: sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==} + engines: {node: '>=6.0.0'} + + espree@7.3.1: + resolution: {integrity: sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==} + engines: {node: ^10.12.0 || >=12.0.0} + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + esquery@1.7.0: + resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@4.3.0: + resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + + event-pubsub@4.3.0: + resolution: {integrity: sha512-z7IyloorXvKbFx9Bpie2+vMJKKx1fH1EN5yiTfp8CiLOTptSYy1g8H4yDpGlEdshL1PBiFtBHepF2cNsqeEeFQ==} + engines: {node: '>=4.0.0'} + + eventemitter3@2.0.3: + resolution: {integrity: sha512-jLN68Dx5kyFHaePoXWPsCGW5qdyZQtLYHkxkg02/Mz6g0kYpDx4FyP6XfArhQdlOC4b8Mv+EMxPo/8La7Tzghg==} + + eventemitter3@4.0.7: + resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + + eventsource@2.0.2: + resolution: {integrity: sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA==} + engines: {node: '>=12.0.0'} + + evp_bytestokey@1.0.3: + resolution: {integrity: sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==} + + execa@0.8.0: + resolution: {integrity: sha512-zDWS+Rb1E8BlqqhALSt9kUhss8Qq4nN3iof3gsOdyINksElaPyNBtKUMTR62qhvgVWR0CqCX7sdnKe4MnUbFEA==} + engines: {node: '>=4'} + + execa@1.0.0: + resolution: {integrity: sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==} + engines: {node: '>=6'} + + execa@3.4.0: + resolution: {integrity: sha512-r9vdGQk4bmCuK1yKQu1KTwcT2zwfWdbdaXfCtAh+5nU/4fSX+JAb7vZGvI5naJrQlvONrEB20jeruESI69530g==} + engines: {node: ^8.12.0 || >=9.7.0} + + execa@4.1.0: + resolution: {integrity: sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==} + engines: {node: '>=10'} + + expand-brackets@2.1.4: + resolution: {integrity: sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==} + engines: {node: '>=0.10.0'} + + express@4.22.1: + resolution: {integrity: sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==} + engines: {node: '>= 0.10.0'} + + extend-shallow@2.0.1: + resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} + engines: {node: '>=0.10.0'} + + extend-shallow@3.0.2: + resolution: {integrity: sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==} + engines: {node: '>=0.10.0'} + + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + + external-editor@3.1.0: + resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} + engines: {node: '>=4'} + + extglob@2.0.4: + resolution: {integrity: sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==} + engines: {node: '>=0.10.0'} + + extsprintf@1.3.0: + resolution: {integrity: sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==} + engines: {'0': node >=0.6.0} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-diff@1.1.2: + resolution: {integrity: sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig==} + + fast-glob@2.2.7: + resolution: {integrity: sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==} + engines: {node: '>=4.0.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + faye-websocket@0.11.4: + resolution: {integrity: sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==} + engines: {node: '>=0.8.0'} + + figgy-pudding@3.5.2: + resolution: {integrity: sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==} + deprecated: This module is no longer supported. + + figures@3.2.0: + resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} + engines: {node: '>=8'} + + file-entry-cache@6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} + engines: {node: ^10.12.0 || >=12.0.0} + + file-loader@4.3.0: + resolution: {integrity: sha512-aKrYPYjF1yG3oX0kWRrqrSMfgftm7oJW5M+m4owoldH5C51C0RkIwB++JbRvEW3IU6/ZG5n8UvEcdgwOt2UOWA==} + engines: {node: '>= 8.9.0'} + peerDependencies: + webpack: ^4.0.0 + + file-saver@2.0.5: + resolution: {integrity: sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==} + + file-uri-to-path@1.0.0: + resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + + filesize@3.6.1: + resolution: {integrity: sha512-7KjR1vv6qnicaPMi1iiTcI85CyYwRO/PSFCu6SvqL8jN2Wjt/NIYQTFtFs7fSDCYOstUkEWIQGFUg5YZQfjlcg==} + engines: {node: '>= 0.4.0'} + + fill-range@4.0.0: + resolution: {integrity: sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==} + engines: {node: '>=0.10.0'} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + finalhandler@1.1.0: + resolution: {integrity: sha512-ejnvM9ZXYzp6PUPUyQBMBf0Co5VX2gr5H2VQe2Ui2jWXNlxv+PYZo8wpAymJNJdLsG1R4p+M4aynF8KuoUEwRw==} + engines: {node: '>= 0.8'} + + finalhandler@1.3.2: + resolution: {integrity: sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==} + engines: {node: '>= 0.8'} + + find-cache-dir@0.1.1: + resolution: {integrity: sha512-Z9XSBoNE7xQiV6MSgPuCfyMokH2K7JdpRkOYE1+mu3d4BFJtx3GW+f6Bo4q8IX6rlf5MYbLBKW0pjl2cWdkm2A==} + engines: {node: '>=0.10.0'} + + find-cache-dir@2.1.0: + resolution: {integrity: sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==} + engines: {node: '>=6'} + + find-cache-dir@3.3.2: + resolution: {integrity: sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==} + engines: {node: '>=8'} + + find-up@1.1.2: + resolution: {integrity: sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==} + engines: {node: '>=0.10.0'} + + find-up@3.0.0: + resolution: {integrity: sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==} + engines: {node: '>=6'} + + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + + flat-cache@3.2.0: + resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} + engines: {node: ^10.12.0 || >=12.0.0} + + flatted@3.4.2: + resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} + + flush-write-stream@1.1.1: + resolution: {integrity: sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==} + + follow-redirects@1.16.0: + resolution: {integrity: sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + for-each@0.3.5: + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} + engines: {node: '>= 0.4'} + + for-in@1.0.2: + resolution: {integrity: sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==} + engines: {node: '>=0.10.0'} + + forever-agent@0.6.1: + resolution: {integrity: sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==} + + form-data@2.3.3: + resolution: {integrity: sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==} + engines: {node: '>= 0.12'} + + form-data@4.0.5: + resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} + engines: {node: '>= 6'} + + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + + fragment-cache@0.2.1: + resolution: {integrity: sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==} + engines: {node: '>=0.10.0'} + + fresh@0.5.2: + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} + engines: {node: '>= 0.6'} + + from2@2.3.0: + resolution: {integrity: sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==} + + fs-extra@7.0.1: + resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} + engines: {node: '>=6 <7 || >=8'} + + fs-minipass@2.1.0: + resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} + engines: {node: '>= 8'} + + fs-write-stream-atomic@1.0.10: + resolution: {integrity: sha512-gehEzmPn2nAwr39eay+x3X34Ra+M2QlVUTLhkXPjWdeO8RF9kszk116avgBJM3ZyNHgHXBNx+VmPaFC36k0PzA==} + deprecated: This package is no longer supported. + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + fsevents@1.2.13: + resolution: {integrity: sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==} + engines: {node: '>= 4.0'} + os: [darwin] + deprecated: Upgrade to fsevents v2 to mitigate potential security issues + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + function.prototype.name@1.1.8: + resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} + engines: {node: '>= 0.4'} + + functional-red-black-tree@1.0.1: + resolution: {integrity: sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==} + + functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + + fuse.js@6.4.3: + resolution: {integrity: sha512-JNgngolukIrqwayWnvy6NLH63hmwKPhm63o0uyBg51jPD0j09IvAzlV1rTXfAsgxpghI7khAo6Mv+EmvjDWXig==} + engines: {node: '>=10'} + + fuzzysearch@1.0.3: + resolution: {integrity: sha512-s+kNWQuI3mo9OALw0HJ6YGmMbLqEufCh2nX/zzV5CrICQ/y4AwPxM+6TIiF9ItFCHXFCyM/BfCCmN57NTIJuPg==} + + generator-function@2.0.1: + resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==} + engines: {node: '>= 0.4'} + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-own-enumerable-property-symbols@3.0.2: + resolution: {integrity: sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + get-stream@3.0.0: + resolution: {integrity: sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==} + engines: {node: '>=4'} + + get-stream@4.1.0: + resolution: {integrity: sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==} + engines: {node: '>=6'} + + get-stream@5.2.0: + resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} + engines: {node: '>=8'} + + get-symbol-description@1.1.0: + resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} + engines: {node: '>= 0.4'} + + get-value@2.0.6: + resolution: {integrity: sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==} + engines: {node: '>=0.10.0'} + + getpass@0.1.7: + resolution: {integrity: sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==} + + glob-parent@3.1.0: + resolution: {integrity: sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-to-regexp@0.3.0: + resolution: {integrity: sha512-Iozmtbqv0noj0uDDqoL0zNq0VBEfK2YFoMAZoxJe4cwphvLR+JskfF30QhXHOR4m3KrE6NLRYw+U9MRXvifyig==} + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + + globals@12.4.0: + resolution: {integrity: sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==} + engines: {node: '>=8'} + + globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} + engines: {node: '>= 0.4'} + + globby@6.1.0: + resolution: {integrity: sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==} + engines: {node: '>=0.10.0'} + + globby@7.1.1: + resolution: {integrity: sha512-yANWAN2DUcBtuus5Cpd+SKROzXHs2iVXFZt/Ykrfz6SAXqacLX25NZpltE+39ceMexYF4TtEadjuSTw8+3wX4g==} + engines: {node: '>=4'} + + globby@9.2.0: + resolution: {integrity: sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==} + engines: {node: '>=6'} + + good-listener@1.2.2: + resolution: {integrity: sha512-goW1b+d9q/HIwbVYZzZ6SsTr4IgE+WA44A0GmPIQstuOrgsFcT7VEJ48nmr9GaRtNu0XTKacFLGnBPAM6Afouw==} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + gzip-size@5.1.1: + resolution: {integrity: sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA==} + engines: {node: '>=6'} + + handle-thing@2.0.1: + resolution: {integrity: sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==} + + har-schema@2.0.0: + resolution: {integrity: sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==} + engines: {node: '>=4'} + + har-validator@5.1.5: + resolution: {integrity: sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==} + engines: {node: '>=6'} + deprecated: this library is no longer supported + + has-ansi@2.0.0: + resolution: {integrity: sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==} + engines: {node: '>=0.10.0'} + + has-bigints@1.1.0: + resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} + engines: {node: '>= 0.4'} + + has-flag@1.0.0: + resolution: {integrity: sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==} + engines: {node: '>=0.10.0'} + + has-flag@2.0.0: + resolution: {integrity: sha512-P+1n3MnwjR/Epg9BBo1KT8qbye2g2Ou4sFumihwt6I4tsUX7jnLcX4BTOSKg/B1ZrIYMN9FcEnG4x5a7NB8Eng==} + engines: {node: '>=0.10.0'} + + has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.2.0: + resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} + engines: {node: '>= 0.4'} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + has-value@0.3.1: + resolution: {integrity: sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==} + engines: {node: '>=0.10.0'} + + has-value@1.0.0: + resolution: {integrity: sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==} + engines: {node: '>=0.10.0'} + + has-values@0.1.4: + resolution: {integrity: sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==} + engines: {node: '>=0.10.0'} + + has-values@1.0.0: + resolution: {integrity: sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==} + engines: {node: '>=0.10.0'} + + has@1.0.4: + resolution: {integrity: sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==} + engines: {node: '>= 0.4.0'} + + hash-base@3.0.5: + resolution: {integrity: sha512-vXm0l45VbcHEVlTCzs8M+s0VeYsB2lnlAaThoLKGXr3bE/VWDOelNUnycUPEhKEaXARL2TEFjBOyUiM6+55KBg==} + engines: {node: '>= 0.10'} + + hash-base@3.1.2: + resolution: {integrity: sha512-Bb33KbowVTIj5s7Ked1OsqHUeCpz//tPwR+E2zJgJKo9Z5XolZ9b6bdUgjmYlwnWhoOQKoTd1TYToZGn5mAYOg==} + engines: {node: '>= 0.8'} + + hash-sum@1.0.2: + resolution: {integrity: sha512-fUs4B4L+mlt8/XAtSOGMUO1TXmAelItBPtJG7CyHJfYTdDjwisntGO2JQz7oUsatOY9o68+57eziUVNw/mRHmA==} + + hash-sum@2.0.0: + resolution: {integrity: sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==} + + hash.js@1.1.7: + resolution: {integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==} + + hasown@2.0.3: + resolution: {integrity: sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==} + engines: {node: '>= 0.4'} + + he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true + + hex-color-regex@1.1.0: + resolution: {integrity: sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==} + + highlight.js@10.7.3: + resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==} + + highlight.js@9.18.5: + resolution: {integrity: sha512-a5bFyofd/BHCX52/8i8uJkjr9DYwXIPnM/plwI6W7ezItLGqzt7X2G2nXuYSfsIJdkwwj/g9DG1LkcGJI/dDoA==} + deprecated: Support has ended for 9.x series. Upgrade to @latest + + hmac-drbg@1.0.1: + resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==} + + hoopy@0.1.4: + resolution: {integrity: sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==} + engines: {node: '>= 6.0.0'} + + hosted-git-info@2.8.9: + resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} + + hpack.js@2.1.6: + resolution: {integrity: sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==} + + hsl-regex@1.0.0: + resolution: {integrity: sha512-M5ezZw4LzXbBKMruP+BNANf0k+19hDQMgpzBIYnya//Al+fjNct9Wf3b1WedLqdEs2hKBvxq/jh+DsHJLj0F9A==} + + hsla-regex@1.0.0: + resolution: {integrity: sha512-7Wn5GMLuHBjZCb2bTmnDOycho0p/7UVaAeqXZGbHrBCl6Yd/xDhQJAXe6Ga9AXJH2I5zY1dEdYw2u1UptnSBJA==} + + html-entities@1.4.0: + resolution: {integrity: sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA==} + + html-minifier@3.5.21: + resolution: {integrity: sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA==} + engines: {node: '>=4'} + hasBin: true + + html-tags@2.0.0: + resolution: {integrity: sha512-+Il6N8cCo2wB/Vd3gqy/8TZhTD3QvcVeQLCnZiGkGCH3JP28IgGAY41giccp2W4R3jfyJPAP318FQTa1yU7K7g==} + engines: {node: '>=4'} + + html-webpack-plugin@3.2.0: + resolution: {integrity: sha512-Br4ifmjQojUP4EmHnRBoUIYcZ9J7M4bTMcm7u6xoIAIuq2Nte4TzXX0533owvkQKQD1WeMTTTyD4Ni4QKxS0Bg==} + engines: {node: '>=6.9'} + deprecated: 3.x is no longer supported + peerDependencies: + webpack: ^1.0.0 || ^2.0.0 || ^3.0.0 || ^4.0.0 + + htmlparser2@3.10.1: + resolution: {integrity: sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==} + + htmlparser2@6.1.0: + resolution: {integrity: sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==} + + http-deceiver@1.2.7: + resolution: {integrity: sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==} + + http-errors@1.8.1: + resolution: {integrity: sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==} + engines: {node: '>= 0.6'} + + http-errors@2.0.1: + resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} + engines: {node: '>= 0.8'} + + http-parser-js@0.5.10: + resolution: {integrity: sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==} + + http-proxy-middleware@0.19.1: + resolution: {integrity: sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==} + engines: {node: '>=4.0.0'} + + http-proxy@1.18.1: + resolution: {integrity: sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==} + engines: {node: '>=8.0.0'} + + http-signature@1.2.0: + resolution: {integrity: sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==} + engines: {node: '>=0.8', npm: '>=1.3.7'} + + https-browserify@1.0.0: + resolution: {integrity: sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==} + + human-signals@1.1.1: + resolution: {integrity: sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==} + engines: {node: '>=8.12.0'} + + iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + + icss-utils@4.1.1: + resolution: {integrity: sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==} + engines: {node: '>= 6'} + + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + + iferr@0.1.5: + resolution: {integrity: sha512-DUNFN5j7Tln0D+TxzloUjKB+CtVu6myn0JEFak6dG18mNt9YkQ6lzGCdafwofISZ1lLF3xRHJ98VKy9ynkcFaA==} + + ignore@3.3.10: + resolution: {integrity: sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==} + + ignore@4.0.6: + resolution: {integrity: sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==} + engines: {node: '>= 4'} + + image-size@0.5.5: + resolution: {integrity: sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==} + engines: {node: '>=0.10.0'} + hasBin: true + + import-cwd@2.1.0: + resolution: {integrity: sha512-Ew5AZzJQFqrOV5BTW3EIoHAnoie1LojZLXKcCQ/yTRyVZosBhK1x1ViYjHGf5pAFOq8ZyChZp6m/fSN7pJyZtg==} + engines: {node: '>=4'} + + import-fresh@2.0.0: + resolution: {integrity: sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==} + engines: {node: '>=4'} + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + + import-from@2.1.0: + resolution: {integrity: sha512-0vdnLL2wSGnhlRmzHJAg5JHjt1l2vYhzJ7tNLGbeVg0fse56tpGaH0uzH+r9Slej+BSXXEHvBKDEnVSLLE9/+w==} + engines: {node: '>=4'} + + import-local@2.0.0: + resolution: {integrity: sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==} + engines: {node: '>=6'} + hasBin: true + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + + indexes-of@1.0.1: + resolution: {integrity: sha512-bup+4tap3Hympa+JBJUG7XuOsdNQ6fxt0MHyXMKuLBKn0OqsTfvUxkUrroEX1+B2VsSHvCjiIcZVxRtYa4nllA==} + + infer-owner@1.0.4: + resolution: {integrity: sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.3: + resolution: {integrity: sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==} + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + + inquirer@7.3.3: + resolution: {integrity: sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==} + engines: {node: '>=8.0.0'} + + internal-ip@4.3.0: + resolution: {integrity: sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==} + engines: {node: '>=6'} + + internal-slot@1.1.0: + resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} + engines: {node: '>= 0.4'} + + ip-regex@2.1.0: + resolution: {integrity: sha512-58yWmlHpp7VYfcdTwMTvwMmqx/Elfxjd9RXTDyMsbL7lLWmhMylLEqiYVLKuLzOZqVgiWXD9MfR62Vv89VRxkw==} + engines: {node: '>=4'} + + ip@1.1.9: + resolution: {integrity: sha512-cyRxvOEpNHNtchU3Ln9KC/auJgup87llfQpQ+t5ghoC/UhL16SWzbueiCsdTnWmqAWl7LadfuwhlqmtOaqMHdQ==} + + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + + is-absolute-url@2.1.0: + resolution: {integrity: sha512-vOx7VprsKyllwjSkLV79NIhpyLfr3jAp7VaTCMXOJHu4m0Ew1CZ2fcjASwmV1jI3BWuWHB013M48eyeldk9gYg==} + engines: {node: '>=0.10.0'} + + is-absolute-url@3.0.3: + resolution: {integrity: sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==} + engines: {node: '>=8'} + + is-accessor-descriptor@1.0.1: + resolution: {integrity: sha512-YBUanLI8Yoihw923YeFUS5fs0fF2f5TSFTNiYAAzhhDscDa3lEqYuz1pDOEP5KvX94I9ey3vsqjJcLVFVU+3QA==} + engines: {node: '>= 0.10'} + + is-arguments@1.2.0: + resolution: {integrity: sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==} + engines: {node: '>= 0.4'} + + is-array-buffer@3.0.5: + resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} + engines: {node: '>= 0.4'} + + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + + is-arrayish@0.3.4: + resolution: {integrity: sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==} + + is-async-function@2.1.1: + resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} + engines: {node: '>= 0.4'} + + is-bigint@1.1.0: + resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} + engines: {node: '>= 0.4'} + + is-binary-path@1.0.1: + resolution: {integrity: sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==} + engines: {node: '>=0.10.0'} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-boolean-object@1.2.2: + resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} + engines: {node: '>= 0.4'} + + is-buffer@1.1.6: + resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-ci@1.2.1: + resolution: {integrity: sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==} + hasBin: true + + is-color-stop@1.1.0: + resolution: {integrity: sha512-H1U8Vz0cfXNujrJzEcvvwMDW9Ra+biSYA3ThdQvAnMLJkEHQXn6bWzLkxHtVYJ+Sdbx0b6finn3jZiaVe7MAHA==} + + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + + is-data-descriptor@1.0.1: + resolution: {integrity: sha512-bc4NlCDiCr28U4aEsQ3Qs2491gVq4V8G7MQyws968ImqjKuYtTJXrl7Vq7jsN7Ly/C3xj5KWFrY7sHNeDkAzXw==} + engines: {node: '>= 0.4'} + + is-data-view@1.0.2: + resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} + engines: {node: '>= 0.4'} + + is-date-object@1.1.0: + resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} + engines: {node: '>= 0.4'} + + is-descriptor@0.1.7: + resolution: {integrity: sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==} + engines: {node: '>= 0.4'} + + is-descriptor@1.0.3: + resolution: {integrity: sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==} + engines: {node: '>= 0.4'} + + is-directory@0.3.1: + resolution: {integrity: sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==} + engines: {node: '>=0.10.0'} + + is-docker@2.2.1: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} + engines: {node: '>=8'} + hasBin: true + + is-extendable@0.1.1: + resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} + engines: {node: '>=0.10.0'} + + is-extendable@1.0.1: + resolution: {integrity: sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==} + engines: {node: '>=0.10.0'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-finalizationregistry@1.1.1: + resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} + engines: {node: '>= 0.4'} + + is-fullwidth-code-point@2.0.0: + resolution: {integrity: sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==} + engines: {node: '>=4'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-generator-function@1.1.2: + resolution: {integrity: sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==} + engines: {node: '>= 0.4'} + + is-glob@3.1.0: + resolution: {integrity: sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==} + engines: {node: '>=0.10.0'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} + engines: {node: '>= 0.4'} + + is-negative-zero@2.0.3: + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} + engines: {node: '>= 0.4'} + + is-number-object@1.1.1: + resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} + engines: {node: '>= 0.4'} + + is-number@3.0.0: + resolution: {integrity: sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==} + engines: {node: '>=0.10.0'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-obj@1.0.1: + resolution: {integrity: sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==} + engines: {node: '>=0.10.0'} + + is-obj@2.0.0: + resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} + engines: {node: '>=8'} + + is-path-cwd@2.2.0: + resolution: {integrity: sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==} + engines: {node: '>=6'} + + is-path-in-cwd@2.1.0: + resolution: {integrity: sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==} + engines: {node: '>=6'} + + is-path-inside@2.1.0: + resolution: {integrity: sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==} + engines: {node: '>=6'} + + is-plain-obj@1.1.0: + resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==} + engines: {node: '>=0.10.0'} + + is-plain-object@2.0.4: + resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} + engines: {node: '>=0.10.0'} + + is-promise@2.2.2: + resolution: {integrity: sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==} + + is-regex@1.2.1: + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} + engines: {node: '>= 0.4'} + + is-regexp@1.0.0: + resolution: {integrity: sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==} + engines: {node: '>=0.10.0'} + + is-resolvable@1.1.0: + resolution: {integrity: sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==} + + is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} + engines: {node: '>= 0.4'} + + is-shared-array-buffer@1.0.4: + resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} + engines: {node: '>= 0.4'} + + is-stream@1.1.0: + resolution: {integrity: sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==} + engines: {node: '>=0.10.0'} + + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + + is-string@1.1.1: + resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} + engines: {node: '>= 0.4'} + + is-symbol@1.1.1: + resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} + engines: {node: '>= 0.4'} + + is-typed-array@1.1.15: + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} + engines: {node: '>= 0.4'} + + is-typedarray@1.0.0: + resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} + + is-unicode-supported@0.1.0: + resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} + engines: {node: '>=10'} + + is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} + + is-weakref@1.1.1: + resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} + engines: {node: '>= 0.4'} + + is-weakset@2.0.4: + resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} + engines: {node: '>= 0.4'} + + is-windows@1.0.2: + resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} + engines: {node: '>=0.10.0'} + + is-wsl@1.1.0: + resolution: {integrity: sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw==} + engines: {node: '>=4'} + + is-wsl@2.2.0: + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} + engines: {node: '>=8'} + + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + isobject@2.1.0: + resolution: {integrity: sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==} + engines: {node: '>=0.10.0'} + + isobject@3.0.1: + resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} + engines: {node: '>=0.10.0'} + + isstream@0.1.2: + resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} + + javascript-stringify@2.1.0: + resolution: {integrity: sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==} + + jest-worker@25.5.0: + resolution: {integrity: sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw==} + engines: {node: '>= 8.3'} + + js-base64@2.6.4: + resolution: {integrity: sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==} + + js-beautify@1.13.0: + resolution: {integrity: sha512-/Tbp1OVzZjbwzwJQFIlYLm9eWQ+3aYbBXLSaqb1mEJzhcQAfrqMMQYtjb6io+U6KpD0ID4F+Id3/xcjH3l/sqA==} + hasBin: true + + js-cookie@3.0.1: + resolution: {integrity: sha512-+0rgsUXZu4ncpPxRL+lNEptWMOWl9etvPHc/koSRp6MPwpRYAhmk0dUG00J4bxVV3r9uUzfo24wW0knS07SKSw==} + engines: {node: '>=12'} + + js-message@1.0.7: + resolution: {integrity: sha512-efJLHhLjIyKRewNS9EGZ4UpI8NguuL6fKkhRxVuMmrGV2xN/0APGdQYwLFky5w9naebSZ0OwAGp0G6/2Cg90rA==} + engines: {node: '>=0.6.0'} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@3.14.2: + resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==} + hasBin: true + + jsbn@0.1.1: + resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==} + + jsencrypt@3.0.0-rc.1: + resolution: {integrity: sha512-gcvGaqerlUJy1Kq6tNgPYteVEoWNemu+9hBe2CdsCIz4rVcwjoTQ72iD1W76/PRMlnkzG0yVh7nwOOMOOUfKmg==} + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-parse-better-errors@1.0.2: + resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==} + + json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-schema@0.4.0: + resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json-stringify-safe@5.0.1: + resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + + json5@0.5.1: + resolution: {integrity: sha512-4xrs1aW+6N5DalkqSVA8fxh458CXvR99WU8WLKmq4v8eWAL86Xo3BVqyd3SkA9wEVjCMqyvvRRkshAdOnBp5rw==} + hasBin: true + + json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsonfile@4.0.0: + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + + jsprim@1.4.2: + resolution: {integrity: sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==} + engines: {node: '>=0.6.0'} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + killable@1.0.1: + resolution: {integrity: sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==} + + kind-of@3.2.2: + resolution: {integrity: sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==} + engines: {node: '>=0.10.0'} + + kind-of@4.0.0: + resolution: {integrity: sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==} + engines: {node: '>=0.10.0'} + + kind-of@5.1.0: + resolution: {integrity: sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==} + engines: {node: '>=0.10.0'} + + kind-of@6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + + klona@2.0.6: + resolution: {integrity: sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==} + engines: {node: '>= 8'} + + launch-editor-middleware@2.13.2: + resolution: {integrity: sha512-kI7VqA9g6mhoeQ6YdNgd+gKLaeuWHAUR8oDM8vFtt924wG8HbI2XO0n/hSX2ML4hcJbTgUihuPHfpnPjIKMdJg==} + + launch-editor@2.13.2: + resolution: {integrity: sha512-4VVDnbOpLXy/s8rdRCSXb+zfMeFR0WlJWpET1iA9CQdlZDfwyLjUuGQzXU4VeOoey6AicSAluWan7Etga6Kcmg==} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + lint-staged@10.5.3: + resolution: {integrity: sha512-TanwFfuqUBLufxCc3RUtFEkFraSPNR3WzWcGF39R3f2J7S9+iF9W0KTVLfSy09lYGmZS5NDCxjNvhGMSJyFCWg==} + hasBin: true + + listr2@3.14.0: + resolution: {integrity: sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==} + engines: {node: '>=10.0.0'} + peerDependencies: + enquirer: '>= 2.3.0 < 3' + peerDependenciesMeta: + enquirer: + optional: true + + loader-fs-cache@1.0.3: + resolution: {integrity: sha512-ldcgZpjNJj71n+2Mf6yetz+c9bM4xpKtNds4LbqXzU/PTdeAX0g3ytnU1AJMEcTk2Lex4Smpe3Q/eCTsvUBxbA==} + + loader-runner@2.4.0: + resolution: {integrity: sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==} + engines: {node: '>=4.3.0 <5.0.0 || >=5.10'} + + loader-utils@0.2.17: + resolution: {integrity: sha512-tiv66G0SmiOx+pLWMtGEkfSEejxvb6N6uRrQjfWJIT79W9GMpgKeCAmm9aVBKtd4WEgntciI8CsGqjpDoCWJug==} + + loader-utils@1.4.2: + resolution: {integrity: sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==} + engines: {node: '>=4.0.0'} + + loader-utils@2.0.4: + resolution: {integrity: sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==} + engines: {node: '>=8.9.0'} + + locate-path@3.0.0: + resolution: {integrity: sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==} + engines: {node: '>=6'} + + locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + + lodash.debounce@4.0.8: + resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} + + lodash.defaultsdeep@4.6.1: + resolution: {integrity: sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA==} + + lodash.kebabcase@4.1.1: + resolution: {integrity: sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==} + + lodash.mapvalues@4.6.0: + resolution: {integrity: sha512-JPFqXFeZQ7BfS00H58kClY7SPVeHertPE0lNuCyZ26/XlN8TvakYD7b9bGyNmXbT/D3BbtPAAmq90gPWqLkxlQ==} + + lodash.memoize@4.1.2: + resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} + + lodash.padend@4.6.1: + resolution: {integrity: sha512-sOQs2aqGpbl27tmCS1QNZA09Uqp01ZzWfDUoD+xzTii0E7dSQfRKcRetFwa+uXaxaqL+TKm7CgD2JdKP7aZBSw==} + + lodash.transform@4.6.0: + resolution: {integrity: sha512-LO37ZnhmBVx0GvOU/caQuipEh4GN82TcWv3yHlebGDgOxbxiwwzW5Pcx2AcvpIv2WmvmSMoC492yQFNhy/l/UQ==} + + lodash.uniq@4.5.0: + resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} + + lodash@4.17.11: + resolution: {integrity: sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==} + + lodash@4.18.1: + resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==} + + log-symbols@2.2.0: + resolution: {integrity: sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==} + engines: {node: '>=4'} + + log-symbols@4.1.0: + resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} + engines: {node: '>=10'} + + log-update@4.0.0: + resolution: {integrity: sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==} + engines: {node: '>=10'} + + loglevel@1.9.2: + resolution: {integrity: sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==} + engines: {node: '>= 0.6.0'} + + lower-case@1.1.4: + resolution: {integrity: sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==} + + lru-cache@4.1.5: + resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + + make-dir@2.1.0: + resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==} + engines: {node: '>=6'} + + make-dir@3.1.0: + resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} + engines: {node: '>=8'} + + map-cache@0.2.2: + resolution: {integrity: sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==} + engines: {node: '>=0.10.0'} + + map-visit@1.0.0: + resolution: {integrity: sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==} + engines: {node: '>=0.10.0'} + + material-colors@1.2.6: + resolution: {integrity: sha512-6qE4B9deFBIa9YSpOc9O0Sgc43zTeVYbgDT5veRKSlB2+ZuHNoVVxA1L/ckMUayV9Ay9y7Z/SZCLcGteW9i7bg==} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + md5.js@1.3.5: + resolution: {integrity: sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==} + + mdn-data@2.0.14: + resolution: {integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==} + + mdn-data@2.0.4: + resolution: {integrity: sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==} + + media-typer@0.3.0: + resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} + engines: {node: '>= 0.6'} + + memory-fs@0.4.1: + resolution: {integrity: sha512-cda4JKCxReDXFXRqOHPQscuIYg1PvxbE2S2GP45rnwfEK+vZaXC8C1OFvdHIbgw0DLzowXGVoxLaAmlgRy14GQ==} + + memory-fs@0.5.0: + resolution: {integrity: sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==} + engines: {node: '>=4.3.0 <5.0.0 || >=5.10'} + + merge-descriptors@1.0.3: + resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} + + merge-options@1.0.1: + resolution: {integrity: sha512-iuPV41VWKWBIOpBsjoxjDZw8/GbSfZ2mk7N1453bwMrfzdrIk7EzBd+8UVR6rkw67th7xnk9Dytl3J+lHPdxvg==} + engines: {node: '>=4'} + + merge-source-map@1.1.0: + resolution: {integrity: sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==} + + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + methods@1.1.2: + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} + engines: {node: '>= 0.6'} + + microargs@1.1.2: + resolution: {integrity: sha512-fUrX9ozzzUX6JlDoNXmUM5i4B0uBF5xPznZ0Y/izM9wOtAaTf44V2vUCRgGBLUq/SeGIcDgfnEZDVoT92HId0g==} + engines: {node: '>=6.16.0'} + deprecated: This project has been renamed to @pawelgalazka/cli-args. Install using @pawelgalazka/cli-args instead + + microcli@1.3.3: + resolution: {integrity: sha512-1isRaEBpfRC8vJMJymKknAH8CdPFABuWPVc18rlRWHOCcHLYEkJxcoH7FNkX7AuTGrB4Uf1ve6B0s/FfwzGWKg==} + engines: {node: '>=6.16.0'} + deprecated: This project has been renamed to @pawelgalazka/cli . Install using @pawelgalazka/cli instead + + micromatch@3.1.0: + resolution: {integrity: sha512-3StSelAE+hnRvMs8IdVW7Uhk8CVed5tp+kLLGlBP6WiRAXS21GPGu/Nat4WNPXj2Eoc24B02SaeoyozPMfj0/g==} + engines: {node: '>=0.10.0'} + + micromatch@3.1.10: + resolution: {integrity: sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==} + engines: {node: '>=0.10.0'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + miller-rabin@4.0.1: + resolution: {integrity: sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==} + hasBin: true + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-db@1.54.0: + resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + + mime@2.6.0: + resolution: {integrity: sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==} + engines: {node: '>=4.0.0'} + hasBin: true + + mimic-fn@1.2.0: + resolution: {integrity: sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==} + engines: {node: '>=4'} + + mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + + mini-css-extract-plugin@0.9.0: + resolution: {integrity: sha512-lp3GeY7ygcgAmVIcRPBVhIkf8Us7FZjA+ILpal44qLdSu11wmjKQ3d9k15lfD7pO4esu9eUIAW7qiYIBppv40A==} + engines: {node: '>= 6.9.0'} + peerDependencies: + webpack: ^4.4.0 + + minimalistic-assert@1.0.1: + resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} + + minimalistic-crypto-utils@1.0.1: + resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==} + + minimatch@10.2.5: + resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} + engines: {node: 18 || 20 || >=22} + + minimatch@3.1.5: + resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + minipass-collect@1.0.2: + resolution: {integrity: sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==} + engines: {node: '>= 8'} + + minipass-flush@1.0.7: + resolution: {integrity: sha512-TbqTz9cUwWyHS2Dy89P3ocAGUGxKjjLuR9z8w4WUTGAVgEj17/4nhgo2Du56i0Fm3Pm30g4iA8Lcqctc76jCzA==} + engines: {node: '>= 8'} + + minipass-pipeline@1.2.4: + resolution: {integrity: sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==} + engines: {node: '>=8'} + + minipass@3.3.6: + resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} + engines: {node: '>=8'} + + minipass@5.0.0: + resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} + engines: {node: '>=8'} + + minizlib@2.1.2: + resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} + engines: {node: '>= 8'} + + mississippi@3.0.0: + resolution: {integrity: sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==} + engines: {node: '>=4.0.0'} + + mitt@1.1.2: + resolution: {integrity: sha512-3btxP0O9iGADGWAkteQ8mzDtEspZqu4I32y4GZYCV5BrwtzdcRpF4dQgNdJadCrbBx7Lu6Sq9AVrerMHR0Hkmw==} + + mixin-deep@1.3.2: + resolution: {integrity: sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==} + engines: {node: '>=0.10.0'} + + mkdirp@0.5.6: + resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} + hasBin: true + + mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + + move-concurrently@1.0.1: + resolution: {integrity: sha512-hdrFxZOycD/g6A6SoI2bB5NA/5NEqD0569+S47WZhPvm46sD50ZHdYaFmnua5lndde9rCHGjmfK7Z8BuCt/PcQ==} + deprecated: This package is no longer supported. + + ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + multicast-dns-service-types@1.1.0: + resolution: {integrity: sha512-cnAsSVxIDsYt0v7HmC0hWZFwwXSh+E6PgCrREDuN/EsjgLwA5XRmlMHhSiDPrt6HxY1gTivEa/Zh7GtODoLevQ==} + + multicast-dns@7.2.5: + resolution: {integrity: sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==} + hasBin: true + + mute-stream@0.0.8: + resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} + + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + + nan@2.26.2: + resolution: {integrity: sha512-0tTvBTYkt3tdGw22nrAy50x7gpbGCCFH3AFcyS5WiUu7Eu4vWlri1woE6qHBSfy11vksDqkiwjOnlR7WV8G1Hw==} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + nanomatch@1.2.13: + resolution: {integrity: sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==} + engines: {node: '>=0.10.0'} + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + negotiator@0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + + negotiator@0.6.4: + resolution: {integrity: sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==} + engines: {node: '>= 0.6'} + + neo-async@2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + + nice-try@1.0.5: + resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} + + no-case@2.3.2: + resolution: {integrity: sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==} + + node-forge@0.10.0: + resolution: {integrity: sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==} + engines: {node: '>= 6.0.0'} + + node-libs-browser@2.2.1: + resolution: {integrity: sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==} + + node-releases@2.0.38: + resolution: {integrity: sha512-3qT/88Y3FbH/Kx4szpQQ4HzUbVrHPKTLVpVocKiLfoYvw9XSGOX2FmD2d6DrXbVYyAQTF2HeF6My8jmzx7/CRw==} + + nopt@5.0.0: + resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==} + engines: {node: '>=6'} + hasBin: true + + normalize-package-data@2.5.0: + resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} + + normalize-path@1.0.0: + resolution: {integrity: sha512-7WyT0w8jhpDStXRq5836AMmihQwq2nrUVQrgjvUo/p/NZf9uy/MeJ246lBJVmWuYXMlJuG9BNZHF0hWjfTbQUA==} + engines: {node: '>=0.10.0'} + + normalize-path@2.1.1: + resolution: {integrity: sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==} + engines: {node: '>=0.10.0'} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + normalize-range@0.1.2: + resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} + engines: {node: '>=0.10.0'} + + normalize-url@1.9.1: + resolution: {integrity: sha512-A48My/mtCklowHBlI8Fq2jFWK4tX4lJ5E6ytFsSOq1fzpvT0SQSgKhSg7lN5c2uYFOrUAOQp6zhhJnpp1eMloQ==} + engines: {node: '>=4'} + + normalize-url@3.3.0: + resolution: {integrity: sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==} + engines: {node: '>=6'} + + normalize-wheel@1.0.1: + resolution: {integrity: sha512-1OnlAPZ3zgrk8B91HyRj+eVv+kS5u+Z0SCsak6Xil/kmgEia50ga7zfkumayonZrImffAxPU/5WcyGhzetHNPA==} + + npm-run-path@2.0.2: + resolution: {integrity: sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==} + engines: {node: '>=4'} + + npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + + nprogress@0.2.0: + resolution: {integrity: sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==} + + nth-check@1.0.2: + resolution: {integrity: sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==} + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + + num2fraction@1.2.2: + resolution: {integrity: sha512-Y1wZESM7VUThYY+4W+X4ySH2maqcA+p7UR+w8VWNWVAd6lwuXXWz/w/Cz43J/dI2I+PS6wD5N+bJUF+gjWvIqg==} + + oauth-sign@0.9.0: + resolution: {integrity: sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-copy@0.1.0: + resolution: {integrity: sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==} + engines: {node: '>=0.10.0'} + + object-hash@1.3.1: + resolution: {integrity: sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA==} + engines: {node: '>= 0.10.0'} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + object-is@1.1.6: + resolution: {integrity: sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==} + engines: {node: '>= 0.4'} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object-visit@1.0.1: + resolution: {integrity: sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==} + engines: {node: '>=0.10.0'} + + object.assign@4.1.7: + resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} + engines: {node: '>= 0.4'} + + object.getownpropertydescriptors@2.1.9: + resolution: {integrity: sha512-mt8YM6XwsTTovI+kdZdHSxoyF2DI59up034orlC9NfweclcWOt7CVascNNLp6U+bjFVCVCIh9PwS76tDM/rH8g==} + engines: {node: '>= 0.4'} + + object.pick@1.3.0: + resolution: {integrity: sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==} + engines: {node: '>=0.10.0'} + + object.values@1.2.1: + resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} + engines: {node: '>= 0.4'} + + obuf@1.1.2: + resolution: {integrity: sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==} + + omelette@0.4.5: + resolution: {integrity: sha512-b0k9uqwF60u15KmVkneVw96VYRtZu2QCbXUQ26SgdyVUgMBzctzIfhNPKAWl4oqJEKpe52CzBYSS+HIKtiK8sw==} + engines: {node: '>=0.8.0'} + + on-finished@2.3.0: + resolution: {integrity: sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==} + engines: {node: '>= 0.8'} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + + on-headers@1.1.0: + resolution: {integrity: sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==} + engines: {node: '>= 0.8'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + onetime@2.0.1: + resolution: {integrity: sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==} + engines: {node: '>=4'} + + onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + + open@6.4.0: + resolution: {integrity: sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg==} + engines: {node: '>=8'} + + opener@1.5.2: + resolution: {integrity: sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==} + hasBin: true + + opn@5.5.0: + resolution: {integrity: sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==} + engines: {node: '>=4'} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + ora@3.4.0: + resolution: {integrity: sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg==} + engines: {node: '>=6'} + + os-browserify@0.3.0: + resolution: {integrity: sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==} + + os-tmpdir@1.0.2: + resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} + engines: {node: '>=0.10.0'} + + own-keys@1.0.1: + resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} + engines: {node: '>= 0.4'} + + p-finally@1.0.0: + resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==} + engines: {node: '>=4'} + + p-finally@2.0.1: + resolution: {integrity: sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==} + engines: {node: '>=8'} + + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + + p-locate@3.0.0: + resolution: {integrity: sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==} + engines: {node: '>=6'} + + p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + + p-map@2.1.0: + resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} + engines: {node: '>=6'} + + p-map@3.0.0: + resolution: {integrity: sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==} + engines: {node: '>=8'} + + p-map@4.0.0: + resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} + engines: {node: '>=10'} + + p-retry@3.0.1: + resolution: {integrity: sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==} + engines: {node: '>=6'} + + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + + pako@1.0.11: + resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} + + parallel-transform@1.2.0: + resolution: {integrity: sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==} + + param-case@2.1.1: + resolution: {integrity: sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w==} + + parchment@1.1.4: + resolution: {integrity: sha512-J5FBQt/pM2inLzg4hEWmzQx/8h8D0CiDxaG3vyp9rKrQRSDgBlhjdP5jQGgosEajXPSQouXGHOmVdgo7QmJuOg==} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parse-asn1@5.1.9: + resolution: {integrity: sha512-fIYNuZ/HastSb80baGOuPRo1O9cf4baWw5WsAp7dBuUzeTD/BoaG8sVTdlPFksBE2lF21dN+A1AnrpIjSWqHHg==} + engines: {node: '>= 0.10'} + + parse-json@4.0.0: + resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==} + engines: {node: '>=4'} + + parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + + parse5-htmlparser2-tree-adapter@6.0.1: + resolution: {integrity: sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==} + + parse5@5.1.1: + resolution: {integrity: sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==} + + parse5@6.0.1: + resolution: {integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==} + + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + pascalcase@0.1.1: + resolution: {integrity: sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==} + engines: {node: '>=0.10.0'} + + path-browserify@0.0.1: + resolution: {integrity: sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==} + + path-dirname@1.0.2: + resolution: {integrity: sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==} + + path-exists@2.1.0: + resolution: {integrity: sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==} + engines: {node: '>=0.10.0'} + + path-exists@3.0.0: + resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} + engines: {node: '>=4'} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-is-inside@1.0.2: + resolution: {integrity: sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==} + + path-key@2.0.1: + resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==} + engines: {node: '>=4'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-to-regexp@0.1.13: + resolution: {integrity: sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA==} + + path-type@3.0.0: + resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==} + engines: {node: '>=4'} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + pbkdf2@3.1.5: + resolution: {integrity: sha512-Q3CG/cYvCO1ye4QKkuH7EXxs3VC/rI1/trd+qX2+PolbaKG0H+bgcZzrTt96mMyRtejk+JMCiLUn3y29W8qmFQ==} + engines: {node: '>= 0.10'} + + performance-now@2.1.0: + resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} + + picocolors@0.2.1: + resolution: {integrity: sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.2: + resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} + engines: {node: '>=8.6'} + + pify@2.3.0: + resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} + engines: {node: '>=0.10.0'} + + pify@3.0.0: + resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} + engines: {node: '>=4'} + + pify@4.0.1: + resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} + engines: {node: '>=6'} + + pinkie-promise@2.0.1: + resolution: {integrity: sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==} + engines: {node: '>=0.10.0'} + + pinkie@2.0.4: + resolution: {integrity: sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==} + engines: {node: '>=0.10.0'} + + pkg-dir@1.0.0: + resolution: {integrity: sha512-c6pv3OE78mcZ92ckebVDqg0aWSoKhOTbwCV6qbCWMk546mAL9pZln0+QsN/yQ7fkucd4+yJPLrCBXNt8Ruk+Eg==} + engines: {node: '>=0.10.0'} + + pkg-dir@3.0.0: + resolution: {integrity: sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==} + engines: {node: '>=6'} + + pkg-dir@4.2.0: + resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} + engines: {node: '>=8'} + + please-upgrade-node@3.2.0: + resolution: {integrity: sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==} + + pnp-webpack-plugin@1.7.0: + resolution: {integrity: sha512-2Rb3vm+EXble/sMXNSu6eoBx8e79gKqhNq9F5ZWW6ERNCTE/Q0wQNne5541tE5vKjfM8hpNCYL+LGc1YTfI0dg==} + engines: {node: '>=6'} + + portfinder@1.0.38: + resolution: {integrity: sha512-rEwq/ZHlJIKw++XtLAO8PPuOQA/zaPJOZJ37BVuN97nLpMJeuDVLVGRwbFoBgLudgdTMP2hdRJP++H+8QOA3vg==} + engines: {node: '>= 10.12'} + + posix-character-classes@0.1.1: + resolution: {integrity: sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==} + engines: {node: '>=0.10.0'} + + possible-typed-array-names@1.1.0: + resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} + engines: {node: '>= 0.4'} + + postcss-calc@7.0.5: + resolution: {integrity: sha512-1tKHutbGtLtEZF6PT4JSihCHfIVldU72mZ8SdZHIYriIZ9fh9k9aWSppaT8rHsyI3dX+KSR+W+Ix9BMY3AODrg==} + + postcss-colormin@4.0.3: + resolution: {integrity: sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw==} + engines: {node: '>=6.9.0'} + + postcss-convert-values@4.0.1: + resolution: {integrity: sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ==} + engines: {node: '>=6.9.0'} + + postcss-discard-comments@4.0.2: + resolution: {integrity: sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg==} + engines: {node: '>=6.9.0'} + + postcss-discard-duplicates@4.0.2: + resolution: {integrity: sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ==} + engines: {node: '>=6.9.0'} + + postcss-discard-empty@4.0.1: + resolution: {integrity: sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w==} + engines: {node: '>=6.9.0'} + + postcss-discard-overridden@4.0.1: + resolution: {integrity: sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg==} + engines: {node: '>=6.9.0'} + + postcss-load-config@2.1.2: + resolution: {integrity: sha512-/rDeGV6vMUo3mwJZmeHfEDvwnTKKqQ0S7OHUi/kJvvtx3aWtyWG2/0ZWnzCt2keEclwN6Tf0DST2v9kITdOKYw==} + engines: {node: '>= 4'} + + postcss-loader@3.0.0: + resolution: {integrity: sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA==} + engines: {node: '>= 6'} + + postcss-merge-longhand@4.0.11: + resolution: {integrity: sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw==} + engines: {node: '>=6.9.0'} + + postcss-merge-rules@4.0.3: + resolution: {integrity: sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ==} + engines: {node: '>=6.9.0'} + + postcss-minify-font-values@4.0.2: + resolution: {integrity: sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg==} + engines: {node: '>=6.9.0'} + + postcss-minify-gradients@4.0.2: + resolution: {integrity: sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q==} + engines: {node: '>=6.9.0'} + + postcss-minify-params@4.0.2: + resolution: {integrity: sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg==} + engines: {node: '>=6.9.0'} + + postcss-minify-selectors@4.0.2: + resolution: {integrity: sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g==} + engines: {node: '>=6.9.0'} + + postcss-modules-extract-imports@2.0.0: + resolution: {integrity: sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==} + engines: {node: '>= 6'} + + postcss-modules-local-by-default@3.0.3: + resolution: {integrity: sha512-e3xDq+LotiGesympRlKNgaJ0PCzoUIdpH0dj47iWAui/kyTgh3CiAr1qP54uodmJhl6p9rN6BoNcdEDVJx9RDw==} + engines: {node: '>= 6'} + + postcss-modules-scope@2.2.0: + resolution: {integrity: sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==} + engines: {node: '>= 6'} + + postcss-modules-values@3.0.0: + resolution: {integrity: sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg==} + + postcss-normalize-charset@4.0.1: + resolution: {integrity: sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g==} + engines: {node: '>=6.9.0'} + + postcss-normalize-display-values@4.0.2: + resolution: {integrity: sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ==} + engines: {node: '>=6.9.0'} + + postcss-normalize-positions@4.0.2: + resolution: {integrity: sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA==} + engines: {node: '>=6.9.0'} + + postcss-normalize-repeat-style@4.0.2: + resolution: {integrity: sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q==} + engines: {node: '>=6.9.0'} + + postcss-normalize-string@4.0.2: + resolution: {integrity: sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA==} + engines: {node: '>=6.9.0'} + + postcss-normalize-timing-functions@4.0.2: + resolution: {integrity: sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A==} + engines: {node: '>=6.9.0'} + + postcss-normalize-unicode@4.0.1: + resolution: {integrity: sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg==} + engines: {node: '>=6.9.0'} + + postcss-normalize-url@4.0.1: + resolution: {integrity: sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA==} + engines: {node: '>=6.9.0'} + + postcss-normalize-whitespace@4.0.2: + resolution: {integrity: sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA==} + engines: {node: '>=6.9.0'} + + postcss-ordered-values@4.1.2: + resolution: {integrity: sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw==} + engines: {node: '>=6.9.0'} + + postcss-prefix-selector@1.16.1: + resolution: {integrity: sha512-Umxu+FvKMwlY6TyDzGFoSUnzW+NOfMBLyC1tAkIjgX+Z/qGspJeRjVC903D7mx7TuBpJlwti2ibXtWuA7fKMeQ==} + peerDependencies: + postcss: '>4 <9' + + postcss-reduce-initial@4.0.3: + resolution: {integrity: sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA==} + engines: {node: '>=6.9.0'} + + postcss-reduce-transforms@4.0.2: + resolution: {integrity: sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg==} + engines: {node: '>=6.9.0'} + + postcss-selector-parser@3.1.2: + resolution: {integrity: sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==} + engines: {node: '>=8'} + + postcss-selector-parser@6.1.2: + resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} + engines: {node: '>=4'} + + postcss-svgo@4.0.3: + resolution: {integrity: sha512-NoRbrcMWTtUghzuKSoIm6XV+sJdvZ7GZSc3wdBN0W19FTtp2ko8NqLsgoh/m9CzNhU3KLPvQmjIwtaNFkaFTvw==} + engines: {node: '>=6.9.0'} + + postcss-unique-selectors@4.0.1: + resolution: {integrity: sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg==} + engines: {node: '>=6.9.0'} + + postcss-value-parser@3.3.1: + resolution: {integrity: sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==} + + postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + + postcss@5.2.18: + resolution: {integrity: sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==} + engines: {node: '>=0.12'} + + postcss@7.0.39: + resolution: {integrity: sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==} + engines: {node: '>=6.0.0'} + + postcss@8.5.10: + resolution: {integrity: sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ==} + engines: {node: ^10 || ^12 || >=14} + + posthtml-parser@0.2.1: + resolution: {integrity: sha512-nPC53YMqJnc/+1x4fRYFfm81KV2V+G9NZY+hTohpYg64Ay7NemWWcV4UWuy/SgMupqQ3kJ88M/iRfZmSnxT+pw==} + + posthtml-rename-id@1.0.12: + resolution: {integrity: sha512-UKXf9OF/no8WZo9edRzvuMenb6AD5hDLzIepJW+a4oJT+T/Lx7vfMYWT4aWlGNQh0WMhnUx1ipN9OkZ9q+ddEw==} + + posthtml-render@1.4.0: + resolution: {integrity: sha512-W1779iVHGfq0Fvh2PROhCe2QhB8mEErgqzo1wpIt36tCgChafP+hbXIhLDOM8ePJrZcFs0vkNEtdibEWVqChqw==} + engines: {node: '>=10'} + + posthtml-svg-mode@1.0.3: + resolution: {integrity: sha512-hEqw9NHZ9YgJ2/0G7CECOeuLQKZi8HjWLkBaSVtOWjygQ9ZD8P7tqeowYs7WrFdKsWEKG7o+IlsPY8jrr0CJpQ==} + + posthtml@0.9.2: + resolution: {integrity: sha512-spBB5sgC4cv2YcW03f/IAUN1pgDJWNWD8FzkyY4mArLUMJW+KlQhlmUdKAHQuPfb00Jl5xIfImeOsf6YL8QK7Q==} + engines: {node: '>=0.10.0'} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prepend-http@1.0.4: + resolution: {integrity: sha512-PhmXi5XmoyKw1Un4E+opM2KcsJInDvKyuOumcjjw3waw86ZNjHwVUOOWLc4bCzLdcKNaWBH9e99sbWzDQsVaYg==} + engines: {node: '>=0.10.0'} + + prettier@2.8.8: + resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} + engines: {node: '>=10.13.0'} + hasBin: true + + pretty-error@2.1.2: + resolution: {integrity: sha512-EY5oDzmsX5wvuynAByrmY0P0hcp+QpnAKbJng2A2MPjVKXCxrDSUkzghVJ4ZGPIv+JC4gX8fPUWscC0RtjsWGw==} + + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + + progress@2.0.3: + resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} + engines: {node: '>=0.4.0'} + + promise-inflight@1.0.1: + resolution: {integrity: sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==} + peerDependencies: + bluebird: '*' + peerDependenciesMeta: + bluebird: + optional: true + + proto-list@1.2.4: + resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} + + proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + + prr@1.0.1: + resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==} + + pseudomap@1.0.2: + resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==} + + psl@1.15.0: + resolution: {integrity: sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==} + + public-encrypt@4.0.3: + resolution: {integrity: sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==} + + pump@2.0.1: + resolution: {integrity: sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==} + + pump@3.0.4: + resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==} + + pumpify@1.5.1: + resolution: {integrity: sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==} + + punycode@1.4.1: + resolution: {integrity: sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + q@1.5.1: + resolution: {integrity: sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==} + engines: {node: '>=0.6.0', teleport: '>=0.2.0'} + deprecated: |- + You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other. + + (For a CapTP with native promises, see @endo/eventual-send and @endo/captp) + + qs@6.14.2: + resolution: {integrity: sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==} + engines: {node: '>=0.6'} + + qs@6.15.1: + resolution: {integrity: sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==} + engines: {node: '>=0.6'} + + qs@6.5.5: + resolution: {integrity: sha512-mzR4sElr1bfCaPJe7m8ilJ6ZXdDaGoObcYR0ZHSsktM/Lt21MVHj5De30GQH2eiZ1qGRTO7LCAzQsUeXTNexWQ==} + engines: {node: '>=0.6'} + + query-string@4.3.4: + resolution: {integrity: sha512-O2XLNDBIg1DnTOa+2XrIwSiXEV8h2KImXUnjhhn2+UsvZ+Es2uyd5CCRTNQlDGbzUQOW3aYCBx9rVA6dzsiY7Q==} + engines: {node: '>=0.10.0'} + + querystring-es3@0.2.1: + resolution: {integrity: sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==} + engines: {node: '>=0.4.x'} + + querystringify@2.2.0: + resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} + + quill-delta@3.6.3: + resolution: {integrity: sha512-wdIGBlcX13tCHOXGMVnnTVFtGRLoP0imqxM696fIPwIf5ODIYUHIvHbZcyvGlZFiFhK5XzDC2lpjbxRhnM05Tg==} + engines: {node: '>=0.10'} + + quill@1.3.7: + resolution: {integrity: sha512-hG/DVzh/TiknWtE6QmWAF/pxoZKYxfe3J/d/+ShUWkDvvkZQVTPeVmUJVu1uE6DDooC4fWTiCLh84ul89oNz5g==} + + randombytes@2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + + randomfill@1.0.4: + resolution: {integrity: sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==} + + range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + + raw-body@2.5.3: + resolution: {integrity: sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==} + engines: {node: '>= 0.8'} + + read-pkg@5.2.0: + resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==} + engines: {node: '>=8'} + + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + readdirp@2.2.1: + resolution: {integrity: sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==} + engines: {node: '>=0.10'} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + reflect.getprototypeof@1.0.10: + resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} + engines: {node: '>= 0.4'} + + regenerate-unicode-properties@10.2.2: + resolution: {integrity: sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==} + engines: {node: '>=4'} + + regenerate@1.4.2: + resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} + + regenerator-runtime@0.11.1: + resolution: {integrity: sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==} + + regex-not@1.0.2: + resolution: {integrity: sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==} + engines: {node: '>=0.10.0'} + + regexp.prototype.flags@1.5.4: + resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} + engines: {node: '>= 0.4'} + + regexpp@3.2.0: + resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==} + engines: {node: '>=8'} + + regexpu-core@6.4.0: + resolution: {integrity: sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==} + engines: {node: '>=4'} + + regjsgen@0.8.0: + resolution: {integrity: sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==} + + regjsparser@0.13.1: + resolution: {integrity: sha512-dLsljMd9sqwRkby8zhO1gSg3PnJIBFid8f4CQj/sXx+7cKx+E7u0PKhZ+U4wmhx7EfmtvnA318oVaIkAB1lRJw==} + hasBin: true + + relateurl@0.2.7: + resolution: {integrity: sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==} + engines: {node: '>= 0.10'} + + remove-trailing-separator@1.1.0: + resolution: {integrity: sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==} + + renderkid@2.0.7: + resolution: {integrity: sha512-oCcFyxaMrKsKcTY59qnCAtmDVSLfPbrv6A3tVbPdFMMrv5jaK10V6m40cKsoPNhAqN6rmHW9sswW4o3ruSrwUQ==} + + repeat-element@1.1.4: + resolution: {integrity: sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==} + engines: {node: '>=0.10.0'} + + repeat-string@1.6.1: + resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} + engines: {node: '>=0.10'} + + request@2.88.2: + resolution: {integrity: sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==} + engines: {node: '>= 6'} + deprecated: request has been deprecated, see https://github.com/request/request/issues/3142 + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + require-main-filename@2.0.0: + resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} + + requires-port@1.0.0: + resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} + + resize-observer-polyfill@1.5.1: + resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==} + + resolve-cwd@2.0.0: + resolution: {integrity: sha512-ccu8zQTrzVr954472aUVPLEcB3YpKSYR3cg/3lo1okzobPBM+1INXBbBZlDbnI/hbEocnf8j0QVo43hQKrbchg==} + engines: {node: '>=4'} + + resolve-from@3.0.0: + resolution: {integrity: sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==} + engines: {node: '>=4'} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve-url@0.2.1: + resolution: {integrity: sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==} + deprecated: https://github.com/lydell/resolve-url#deprecated + + resolve@1.22.12: + resolution: {integrity: sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==} + engines: {node: '>= 0.4'} + hasBin: true + + restore-cursor@2.0.0: + resolution: {integrity: sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==} + engines: {node: '>=4'} + + restore-cursor@3.1.0: + resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} + engines: {node: '>=8'} + + ret@0.1.15: + resolution: {integrity: sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==} + engines: {node: '>=0.12'} + + retry@0.12.0: + resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} + engines: {node: '>= 4'} + + rfdc@1.4.1: + resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} + + rgb-regex@1.0.1: + resolution: {integrity: sha512-gDK5mkALDFER2YLqH6imYvK6g02gpNGM4ILDZ472EwWfXZnC2ZEpoB2ECXTyOVUKuk/bPJZMzwQPBYICzP+D3w==} + + rgba-regex@1.0.0: + resolution: {integrity: sha512-zgn5OjNQXLUTdq8m17KdaicF6w89TZs8ZU8y0AYENIU6wG8GG6LLm0yLSiPY8DmaYmHdgRW8rnApjoT0fQRfMg==} + + rimraf@2.7.1: + resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + ripemd160@2.0.3: + resolution: {integrity: sha512-5Di9UC0+8h1L6ZD2d7awM7E/T4uA1fJRlx6zk/NvdCCVEoAnFqvHmCuNeIKoCeIixBX/q8uM+6ycDvF8woqosA==} + engines: {node: '>= 0.8'} + + run-async@2.4.1: + resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} + engines: {node: '>=0.12.0'} + + run-queue@1.0.3: + resolution: {integrity: sha512-ntymy489o0/QQplUDnpYAYUsO50K9SBrIVaKCWDOJzYJts0f9WH9RFJkyagebkw5+y1oi00R7ynNW/d12GBumg==} + + runjs@4.4.2: + resolution: {integrity: sha512-/DB54HRJnxfGA/a9QLZMyAn8H84SMt8oVGF7Vz+OS4BMCve312DXNRpy6Z8yohLuoMctoalXQtvmpd2ChQYD4Q==} + engines: {node: '>=6.11.1'} + deprecated: This project has been renamed to 'tasksfile'. Install using 'npm install tasksfile' instead. + hasBin: true + + rxjs@6.6.7: + resolution: {integrity: sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==} + engines: {npm: '>=2.0.0'} + + rxjs@7.8.2: + resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} + + safe-array-concat@1.1.4: + resolution: {integrity: sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg==} + engines: {node: '>=0.4'} + + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safe-push-apply@1.0.0: + resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} + engines: {node: '>= 0.4'} + + safe-regex-test@1.1.0: + resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} + engines: {node: '>= 0.4'} + + safe-regex@1.1.0: + resolution: {integrity: sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + sass-loader@10.1.1: + resolution: {integrity: sha512-W6gVDXAd5hR/WHsPicvZdjAWHBcEJ44UahgxcIE196fW2ong0ZHMPO1kZuI5q0VlvMQZh32gpv69PLWQm70qrw==} + engines: {node: '>= 10.13.0'} + peerDependencies: + fibers: '>= 3.1.0' + node-sass: ^4.0.0 || ^5.0.0 + sass: ^1.3.0 + webpack: ^4.36.0 || ^5.0.0 + peerDependenciesMeta: + fibers: + optional: true + node-sass: + optional: true + sass: + optional: true + + sass@1.32.13: + resolution: {integrity: sha512-dEgI9nShraqP7cXQH+lEXVf73WOPCse0QlFzSD8k+1TcOxCMwVXfQlr0jtoluZysQOyJGnfr21dLvYKDJq8HkA==} + engines: {node: '>=8.9.0'} + hasBin: true + + sax@1.2.4: + resolution: {integrity: sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==} + + schema-utils@1.0.0: + resolution: {integrity: sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==} + engines: {node: '>= 4'} + + schema-utils@2.7.1: + resolution: {integrity: sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==} + engines: {node: '>= 8.9.0'} + + schema-utils@3.3.0: + resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==} + engines: {node: '>= 10.13.0'} + + screenfull@5.0.2: + resolution: {integrity: sha512-cCF2b+L/mnEiORLN5xSAz6H3t18i2oHh9BA8+CQlAh5DRw2+NFAGQJOSYbcGw8B2k04g/lVvFcfZ83b3ysH5UQ==} + engines: {node: '>=0.10.0'} + + script-ext-html-webpack-plugin@2.1.5: + resolution: {integrity: sha512-nMjd5dtsnoB8dS+pVM9ZL4mC9O1uVtTxrDS99OGZsZxFbkZE6pw0HCMued/cncDrKivIShO9vwoyOTvsGqQHEQ==} + engines: {node: '>=6.11.5'} + peerDependencies: + html-webpack-plugin: ^3.0.0 || ^4.0.0 + webpack: ^1.0.0 || ^2.0.0 || ^3.0.0 || ^4.0.0 + + select-hose@2.0.0: + resolution: {integrity: sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==} + + select@1.1.2: + resolution: {integrity: sha512-OwpTSOfy6xSs1+pwcNrv0RBMOzI39Lp3qQKUTPVVPRjCdNa5JH/oPRiqsesIskK8TVgmRiHwO4KXlV2Li9dANA==} + + selfsigned@1.10.14: + resolution: {integrity: sha512-lkjaiAye+wBZDCBsu5BGi0XiLRxeUlsGod5ZP924CRSEoGuZAw/f7y9RKu28rwTfiHVhdavhB0qH0INV6P1lEA==} + + semver-compare@1.0.0: + resolution: {integrity: sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==} + + semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.7.4: + resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} + engines: {node: '>=10'} + hasBin: true + + send@0.19.2: + resolution: {integrity: sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==} + engines: {node: '>= 0.8.0'} + + serialize-javascript@4.0.0: + resolution: {integrity: sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==} + + serialize-javascript@5.0.1: + resolution: {integrity: sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==} + + serve-index@1.9.2: + resolution: {integrity: sha512-KDj11HScOaLmrPxl70KYNW1PksP4Nb/CLL2yvC+Qd2kHMPEEpfc4Re2e4FOay+bC/+XQl/7zAcWON3JVo5v3KQ==} + engines: {node: '>= 0.8.0'} + + serve-static@1.16.3: + resolution: {integrity: sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==} + engines: {node: '>= 0.8.0'} + + set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + + set-proto@1.0.0: + resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} + engines: {node: '>= 0.4'} + + set-value@2.0.1: + resolution: {integrity: sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==} + engines: {node: '>=0.10.0'} + + setimmediate@1.0.5: + resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + sha.js@2.4.12: + resolution: {integrity: sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==} + engines: {node: '>= 0.10'} + hasBin: true + + shebang-command@1.2.0: + resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} + engines: {node: '>=0.10.0'} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@1.0.0: + resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} + engines: {node: '>=0.10.0'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + shell-quote@1.8.3: + resolution: {integrity: sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==} + engines: {node: '>= 0.4'} + + side-channel-list@1.0.1: + resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + + sigmund@1.0.1: + resolution: {integrity: sha512-fCvEXfh6NWpm+YSuY2bpXb/VIihqWA6hLsgboC+0nl71Q7N7o2eaCW8mJa/NLvQhs6jpd3VZV4UiUQlV6+lc8g==} + + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + simple-swizzle@0.2.4: + resolution: {integrity: sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==} + + slash@1.0.0: + resolution: {integrity: sha512-3TYDR7xWt4dIqV2JauJr+EJeW356RXijHeUlO+8djJ+uBXPn8/2dpzBc8yQhh583sVvc9CvFAeQVgijsH+PNNg==} + engines: {node: '>=0.10.0'} + + slash@2.0.0: + resolution: {integrity: sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==} + engines: {node: '>=6'} + + slice-ansi@2.1.0: + resolution: {integrity: sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==} + engines: {node: '>=6'} + + slice-ansi@3.0.0: + resolution: {integrity: sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==} + engines: {node: '>=8'} + + slice-ansi@4.0.0: + resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} + engines: {node: '>=10'} + + snapdragon-node@2.1.1: + resolution: {integrity: sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==} + engines: {node: '>=0.10.0'} + + snapdragon-util@3.0.1: + resolution: {integrity: sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==} + engines: {node: '>=0.10.0'} + + snapdragon@0.8.2: + resolution: {integrity: sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==} + engines: {node: '>=0.10.0'} + + sockjs-client@1.6.1: + resolution: {integrity: sha512-2g0tjOR+fRs0amxENLi/q5TiJTqY+WXFOzb5UwXndlK6TO3U/mirZznpx6w34HVMoc3g7cY24yC/ZMIYnDlfkw==} + engines: {node: '>=12'} + + sockjs@0.3.24: + resolution: {integrity: sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==} + + sort-keys@1.1.2: + resolution: {integrity: sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg==} + engines: {node: '>=0.10.0'} + + sortablejs@1.10.2: + resolution: {integrity: sha512-YkPGufevysvfwn5rfdlGyrGjt7/CRHwvRPogD/lC+TnvcN29jDpCifKP+rBqf+LRldfXSTh+0CGLcSg0VIxq3A==} + + source-list-map@2.0.1: + resolution: {integrity: sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + source-map-resolve@0.5.3: + resolution: {integrity: sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==} + deprecated: See https://github.com/lydell/source-map-resolve#deprecated + + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + + source-map-url@0.4.1: + resolution: {integrity: sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==} + deprecated: See https://github.com/lydell/source-map-url#deprecated + + source-map@0.5.7: + resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} + engines: {node: '>=0.10.0'} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + spdx-correct@3.2.0: + resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} + + spdx-exceptions@2.5.0: + resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} + + spdx-expression-parse@3.0.1: + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + + spdx-license-ids@3.0.23: + resolution: {integrity: sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==} + + spdy-transport@3.0.0: + resolution: {integrity: sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==} + + spdy@4.0.2: + resolution: {integrity: sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==} + engines: {node: '>=6.0.0'} + + split-string@3.1.0: + resolution: {integrity: sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==} + engines: {node: '>=0.10.0'} + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + sshpk@1.18.0: + resolution: {integrity: sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==} + engines: {node: '>=0.10.0'} + hasBin: true + + ssri@6.0.2: + resolution: {integrity: sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==} + + ssri@7.1.1: + resolution: {integrity: sha512-w+daCzXN89PseTL99MkA+fxJEcU3wfaE/ah0i0lnOlpG1CYLJ2ZjzEry68YBKfLs4JfoTShrTEsJkAZuNZ/stw==} + engines: {node: '>= 8'} + + ssri@8.0.1: + resolution: {integrity: sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==} + engines: {node: '>= 8'} + + stable@0.1.8: + resolution: {integrity: sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==} + deprecated: 'Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility' + + stackframe@1.3.4: + resolution: {integrity: sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==} + + static-extend@0.1.2: + resolution: {integrity: sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==} + engines: {node: '>=0.10.0'} + + statuses@1.3.1: + resolution: {integrity: sha512-wuTCPGlJONk/a1kqZ4fQM2+908lC7fa7nPYpTC1EhnvqLX/IICbeP1OZGDtA374trpSq68YubKUMo8oRhN46yg==} + engines: {node: '>= 0.6'} + + statuses@1.5.0: + resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} + engines: {node: '>= 0.6'} + + statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + engines: {node: '>= 0.8'} + + stop-iteration-iterator@1.1.0: + resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} + engines: {node: '>= 0.4'} + + stream-browserify@2.0.2: + resolution: {integrity: sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==} + + stream-each@1.2.3: + resolution: {integrity: sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==} + + stream-http@2.8.3: + resolution: {integrity: sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==} + + stream-shift@1.0.3: + resolution: {integrity: sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==} + + strict-uri-encode@1.1.0: + resolution: {integrity: sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==} + engines: {node: '>=0.10.0'} + + string-argv@0.3.1: + resolution: {integrity: sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==} + engines: {node: '>=0.6.19'} + + string-width@3.1.0: + resolution: {integrity: sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==} + engines: {node: '>=6'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string.prototype.trim@1.2.10: + resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} + engines: {node: '>= 0.4'} + + string.prototype.trimend@1.0.9: + resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} + engines: {node: '>= 0.4'} + + string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + stringify-object@3.3.0: + resolution: {integrity: sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==} + engines: {node: '>=4'} + + strip-ansi@3.0.1: + resolution: {integrity: sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==} + engines: {node: '>=0.10.0'} + + strip-ansi@5.2.0: + resolution: {integrity: sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==} + engines: {node: '>=6'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-eof@1.0.0: + resolution: {integrity: sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==} + engines: {node: '>=0.10.0'} + + strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + + strip-indent@2.0.0: + resolution: {integrity: sha512-RsSNPLpq6YUL7QYy44RnPVTn/lcVZtb48Uof3X5JLbF4zD/Gs7ZFDv2HWol+leoQN2mT86LAzSshGfkTlSOpsA==} + engines: {node: '>=4'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + stylehacks@4.0.3: + resolution: {integrity: sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g==} + engines: {node: '>=6.9.0'} + + supports-color@2.0.0: + resolution: {integrity: sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==} + engines: {node: '>=0.8.0'} + + supports-color@3.2.3: + resolution: {integrity: sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==} + engines: {node: '>=0.8.0'} + + supports-color@4.5.0: + resolution: {integrity: sha512-ycQR/UbvI9xIlEdQT1TQqwoXtEldExbCEAJgRo5YXlmSKjv6ThHnP9/vwGa1gr19Gfw+LkFd7KqYMhzrRC5JYw==} + engines: {node: '>=4'} + + supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + + supports-color@6.1.0: + resolution: {integrity: sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==} + engines: {node: '>=6'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + svg-baker-runtime@1.4.7: + resolution: {integrity: sha512-Zorfwwj5+lWjk/oxwSMsRdS2sPQQdTmmsvaSpzU+i9ZWi3zugHLt6VckWfnswphQP0LmOel3nggpF5nETbt6xw==} + + svg-baker@1.7.0: + resolution: {integrity: sha512-nibslMbkXOIkqKVrfcncwha45f97fGuAOn1G99YwnwTj8kF9YiM6XexPcUso97NxOm6GsP0SIvYVIosBis1xLg==} + + svg-sprite-loader@5.1.1: + resolution: {integrity: sha512-oRjDBw3AtZOb+XTx7XE3HcVju9RdnfdXttT3ZJB/vmWGJ+SM+xfXzh3yuVPIpySO8FjGhH5BtU63lGMI9WgYzA==} + engines: {node: '>=6'} + + svg-tags@1.0.0: + resolution: {integrity: sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==} + + svgo@1.3.2: + resolution: {integrity: sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==} + engines: {node: '>=4.0.0'} + deprecated: This SVGO version is no longer supported. Upgrade to v2.x.x. + hasBin: true + + table@5.4.6: + resolution: {integrity: sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==} + engines: {node: '>=6.0.0'} + + tapable@1.1.3: + resolution: {integrity: sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==} + engines: {node: '>=6'} + + tar@6.2.1: + resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} + engines: {node: '>=10'} + deprecated: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + + terser-webpack-plugin@1.4.6: + resolution: {integrity: sha512-2lBVf/VMVIddjSn3GqbT90GvIJ/eYXJkt8cTzU7NbjKqK8fwv18Ftr4PlbF46b/e88743iZFL5Dtr/rC4hjIeA==} + engines: {node: '>= 6.9.0'} + peerDependencies: + webpack: ^4.0.0 + + terser-webpack-plugin@2.3.8: + resolution: {integrity: sha512-/fKw3R+hWyHfYx7Bv6oPqmk4HGQcrWLtV3X6ggvPuwPNHSnzvVV51z6OaaCOus4YLjutYGOz3pEpbhe6Up2s1w==} + engines: {node: '>= 8.9.0'} + peerDependencies: + webpack: ^4.0.0 || ^5.0.0 + + terser@4.8.1: + resolution: {integrity: sha512-4GnLC0x667eJG0ewJTa6z/yXrbLGv80D9Ru6HIpCQmO+Q4PfEtBFi0ObSckqwL6VyQv/7ENJieXHo2ANmdQwgw==} + engines: {node: '>=6.0.0'} + hasBin: true + + text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + + thread-loader@2.1.3: + resolution: {integrity: sha512-wNrVKH2Lcf8ZrWxDF/khdlLlsTMczdcwPA9VEK4c2exlEPynYWxi9op3nPTo5lAnDIkE0rQEB3VBP+4Zncc9Hg==} + engines: {node: '>= 6.9.0 <7.0.0 || >= 8.9.0'} + peerDependencies: + webpack: ^2.0.0 || ^3.0.0 || ^4.0.0 + + throttle-debounce@1.1.0: + resolution: {integrity: sha512-XH8UiPCQcWNuk2LYePibW/4qL97+ZQ1AN3FNXwZRBNPPowo/NRU5fAlDCSNBJIYCKbioZfuYtMhG4quqoJhVzg==} + engines: {node: '>=4'} + + through2@2.0.5: + resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} + + through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + + thunky@1.1.0: + resolution: {integrity: sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==} + + timers-browserify@2.0.12: + resolution: {integrity: sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==} + engines: {node: '>=0.6.0'} + + timsort@0.3.0: + resolution: {integrity: sha512-qsdtZH+vMoCARQtyod4imc2nIJwg9Cc7lPRrw9CzF8ZKR0khdr8+2nX80PBhET3tcyTtJDxAffGh2rXH4tyU8A==} + + tiny-emitter@2.1.0: + resolution: {integrity: sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==} + + tmp@0.0.33: + resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} + engines: {node: '>=0.6.0'} + + to-arraybuffer@1.0.1: + resolution: {integrity: sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA==} + + to-buffer@1.2.2: + resolution: {integrity: sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==} + engines: {node: '>= 0.4'} + + to-object-path@0.3.0: + resolution: {integrity: sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==} + engines: {node: '>=0.10.0'} + + to-regex-range@2.1.1: + resolution: {integrity: sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==} + engines: {node: '>=0.10.0'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + to-regex@3.0.2: + resolution: {integrity: sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==} + engines: {node: '>=0.10.0'} + + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + + toposort@1.0.7: + resolution: {integrity: sha512-FclLrw8b9bMWf4QlCJuHBEVhSRsqDj6u3nIjAzPeJvgl//1hBlffdlk0MALceL14+koWEdU4ofRAXofbODxQzg==} + + tough-cookie@2.5.0: + resolution: {integrity: sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==} + engines: {node: '>=0.8'} + + traverse@0.6.11: + resolution: {integrity: sha512-vxXDZg8/+p3gblxB6BhhG5yWVn1kGRlaL8O78UDXc3wRnPizB5g83dcvWV1jpDMIPnjZjOFuxlMmE82XJ4407w==} + engines: {node: '>= 0.4'} + + tryer@1.0.1: + resolution: {integrity: sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==} + + ts-pnp@1.2.0: + resolution: {integrity: sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw==} + engines: {node: '>=6'} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + tslib@1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + + tslib@2.3.0: + resolution: {integrity: sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + tty-browserify@0.0.0: + resolution: {integrity: sha512-JVa5ijo+j/sOoHGjw0sxw734b1LhBkQ3bvUGNdxnVXDCX81Yx7TFgnZygxrIIWn23hbfTaMYLwRmAxFyDuFmIw==} + + tunnel-agent@0.6.0: + resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + + tweetnacl@0.14.5: + resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + + type-fest@0.6.0: + resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==} + engines: {node: '>=8'} + + type-fest@0.8.1: + resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} + engines: {node: '>=8'} + + type-is@1.6.18: + resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} + engines: {node: '>= 0.6'} + + typed-array-buffer@1.0.3: + resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} + engines: {node: '>= 0.4'} + + typed-array-byte-length@1.0.3: + resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} + engines: {node: '>= 0.4'} + + typed-array-byte-offset@1.0.4: + resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} + engines: {node: '>= 0.4'} + + typed-array-length@1.0.7: + resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} + engines: {node: '>= 0.4'} + + typedarray.prototype.slice@1.0.5: + resolution: {integrity: sha512-q7QNVDGTdl702bVFiI5eY4l/HkgCM6at9KhcFbgUAzezHFbOVy4+0O/lCjsABEQwbZPravVfBIiBVGo89yzHFg==} + engines: {node: '>= 0.4'} + + typedarray@0.0.6: + resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} + + uglify-js@3.4.10: + resolution: {integrity: sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw==} + engines: {node: '>=0.8.0'} + hasBin: true + + unbox-primitive@1.1.0: + resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} + engines: {node: '>= 0.4'} + + undici-types@7.19.2: + resolution: {integrity: sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==} + + unicode-canonical-property-names-ecmascript@2.0.1: + resolution: {integrity: sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==} + engines: {node: '>=4'} + + unicode-match-property-ecmascript@2.0.0: + resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} + engines: {node: '>=4'} + + unicode-match-property-value-ecmascript@2.2.1: + resolution: {integrity: sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==} + engines: {node: '>=4'} + + unicode-property-aliases-ecmascript@2.2.0: + resolution: {integrity: sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==} + engines: {node: '>=4'} + + unidecode@0.1.8: + resolution: {integrity: sha512-SdoZNxCWpN2tXTCrGkPF/0rL2HEq+i2gwRG1ReBvx8/0yTzC3enHfugOf8A9JBShVwwrRIkLX0YcDUGbzjbVCA==} + engines: {node: '>= 0.4.12'} + + union-value@1.0.1: + resolution: {integrity: sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==} + engines: {node: '>=0.10.0'} + + uniq@1.0.1: + resolution: {integrity: sha512-Gw+zz50YNKPDKXs+9d+aKAjVwpjNwqzvNpLigIruT4HA9lMZNdMqs9x07kKHB/L9WRzqp4+DlTU5s4wG2esdoA==} + + uniqs@2.0.0: + resolution: {integrity: sha512-mZdDpf3vBV5Efh29kMw5tXoup/buMgxLzOt/XKFKcVmi+15ManNQWr6HfZ2aiZTYlYixbdNJ0KFmIZIv52tHSQ==} + + unique-filename@1.1.1: + resolution: {integrity: sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==} + + unique-slug@2.0.2: + resolution: {integrity: sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==} + + universalify@0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + engines: {node: '>= 4.0.0'} + + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + unquote@1.1.1: + resolution: {integrity: sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg==} + + unset-value@1.0.0: + resolution: {integrity: sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==} + engines: {node: '>=0.10.0'} + + upath@1.2.0: + resolution: {integrity: sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==} + engines: {node: '>=4'} + + update-browserslist-db@1.2.3: + resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + upper-case@1.1.3: + resolution: {integrity: sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA==} + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + urix@0.1.0: + resolution: {integrity: sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==} + deprecated: Please see https://github.com/lydell/urix#deprecated + + url-loader@2.3.0: + resolution: {integrity: sha512-goSdg8VY+7nPZKUEChZSEtW5gjbS66USIGCeSJ1OVOJ7Yfuh/36YxCwMi5HVEJh6mqUYOoy3NJ0vlOMrWsSHog==} + engines: {node: '>= 8.9.0'} + peerDependencies: + file-loader: '*' + webpack: ^4.0.0 + peerDependenciesMeta: + file-loader: + optional: true + + url-parse@1.5.10: + resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} + + url-slug@2.0.0: + resolution: {integrity: sha512-aiNmSsVgrjCiJ2+KWPferjT46YFKoE8i0YX04BlMVDue022Xwhg/zYlnZ6V9/mP3p8Wj7LEp0myiTkC/p6sxew==} + + url@0.11.4: + resolution: {integrity: sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==} + engines: {node: '>= 0.4'} + + use@3.1.1: + resolution: {integrity: sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==} + engines: {node: '>=0.10.0'} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + util.promisify@1.0.0: + resolution: {integrity: sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==} + + util.promisify@1.0.1: + resolution: {integrity: sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==} + + util@0.10.4: + resolution: {integrity: sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==} + + util@0.11.1: + resolution: {integrity: sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==} + + utila@0.4.0: + resolution: {integrity: sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==} + + utils-merge@1.0.1: + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} + engines: {node: '>= 0.4.0'} + + uuid@3.4.0: + resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==} + deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. + hasBin: true + + uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + + v8-compile-cache@2.4.0: + resolution: {integrity: sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw==} + + validate-npm-package-license@3.0.4: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + vendors@1.0.4: + resolution: {integrity: sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w==} + + verror@1.10.0: + resolution: {integrity: sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==} + engines: {'0': node >=0.6.0} + + vm-browserify@1.1.2: + resolution: {integrity: sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==} + + vue-count-to@1.0.13: + resolution: {integrity: sha512-6R4OVBVNtQTlcbXu6SJ8ENR35M2/CdWt3Jmv57jOUM+1ojiFmjVGvZPH8DfHpMDSA+ITs+EW5V6qthADxeyYOQ==} + + vue-cropper@0.5.5: + resolution: {integrity: sha512-5mGaBlS1EwLxUFwHHX2Q8zOZSiVfBUjOfolR+ZNKwu7Rh3u+GhwHYOyFkgZHhhoQBBNdyVB28O6W+MpMimhCbA==} + + vue-eslint-parser@7.11.0: + resolution: {integrity: sha512-qh3VhDLeh773wjgNTl7ss0VejY9bMMa0GoDG2fQVyDzRFdiU3L7fw74tWZDHNQXdZqxO3EveQroa9ct39D2nqg==} + engines: {node: '>=8.10'} + peerDependencies: + eslint: '>=5.0.0' + + vue-hot-reload-api@2.3.4: + resolution: {integrity: sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==} + + vue-loader@15.11.1: + resolution: {integrity: sha512-0iw4VchYLePqJfJu9s62ACWUXeSqM30SQqlIftbYWM3C+jpPcEHKSPUZBLjSF9au4HTHQ/naF6OGnO3Q/qGR3Q==} + peerDependencies: + '@vue/compiler-sfc': ^3.0.8 + cache-loader: '*' + css-loader: '*' + prettier: '*' + vue-template-compiler: '*' + webpack: ^3.0.0 || ^4.1.0 || ^5.0.0-0 + peerDependenciesMeta: + '@vue/compiler-sfc': + optional: true + cache-loader: + optional: true + prettier: + optional: true + vue-template-compiler: + optional: true + + vue-meta@2.4.0: + resolution: {integrity: sha512-XEeZUmlVeODclAjCNpWDnjgw+t3WA6gdzs6ENoIAgwO1J1d5p1tezDhtteLUFwcaQaTtayRrsx7GL6oXp/m2Jw==} + + vue-router@3.4.9: + resolution: {integrity: sha512-CGAKWN44RqXW06oC+u4mPgHLQQi2t6vLD/JbGRDAXm0YpMv0bgpKuU5bBd7AvMgfTz9kXVRIWKHqRwGEb8xFkA==} + peerDependencies: + vue: ^2 + + vue-style-loader@4.1.3: + resolution: {integrity: sha512-sFuh0xfbtpRlKfm39ss/ikqs9AbKCoXZBpHeVZ8Tx650o0k0q/YCM7FRvigtxpACezfq6af+a7JeqVTWvncqDg==} + + vue-template-compiler@2.6.12: + resolution: {integrity: sha512-OzzZ52zS41YUbkCBfdXShQTe69j1gQDZ9HIX8miuC9C3rBCk9wIRjLiZZLrmX9V+Ftq/YEyv1JaVr5Y/hNtByg==} + + vue-template-es2015-compiler@1.9.1: + resolution: {integrity: sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==} + + vue@2.6.12: + resolution: {integrity: sha512-uhmLFETqPPNyuLLbsKz6ioJ4q7AZHzD8ZVFNATNyICSZouqP2Sz0rotWQC8UNBF6VGSCs5abnKJoStA6JbCbfg==} + deprecated: Vue 2 has reached EOL and is no longer actively maintained. See https://v2.vuejs.org/eol/ for more details. + + vuedraggable@2.24.3: + resolution: {integrity: sha512-6/HDXi92GzB+Hcs9fC6PAAozK1RLt1ewPTLjK0anTYguXLAeySDmcnqE8IC0xa7shvSzRjQXq3/+dsZ7ETGF3g==} + + vuex@3.6.0: + resolution: {integrity: sha512-W74OO2vCJPs9/YjNjW8lLbj+jzT24waTo2KShI8jLvJW8OaIkgb3wuAMA7D+ZiUxDOx3ubwSZTaJBip9G8a3aQ==} + peerDependencies: + vue: ^2.0.0 + + watch-size@2.0.0: + resolution: {integrity: sha512-M92R89dNoTPWyCD+HuUEDdhaDnh9jxPGOwlDc0u51jAgmjUvzqaEMynXSr3BaWs+QdHYk4KzibPy1TFtjLmOZQ==} + + watchpack-chokidar2@2.0.1: + resolution: {integrity: sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww==} + + watchpack@1.7.5: + resolution: {integrity: sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==} + + wbuf@1.7.3: + resolution: {integrity: sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==} + + wcwidth@1.0.1: + resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + + webpack-bundle-analyzer@3.9.0: + resolution: {integrity: sha512-Ob8amZfCm3rMB1ScjQVlbYYUEJyEjdEtQ92jqiFUYt5VkEeO2v5UMbv49P/gnmCZm3A6yaFQzCBvpZqN4MUsdA==} + engines: {node: '>= 6.14.4'} + hasBin: true + + webpack-chain@6.5.1: + resolution: {integrity: sha512-7doO/SRtLu8q5WM0s7vPKPWX580qhi0/yBHkOxNkv50f6qB76Zy9o2wRTrrPULqYTvQlVHuvbA8v+G5ayuUDsA==} + engines: {node: '>=8'} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + + webpack-dev-middleware@3.7.3: + resolution: {integrity: sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ==} + engines: {node: '>= 6'} + peerDependencies: + webpack: ^4.0.0 || ^5.0.0 + + webpack-dev-server@3.11.3: + resolution: {integrity: sha512-3x31rjbEQWKMNzacUZRE6wXvUFuGpH7vr0lIEbYpMAG9BOxi0928QU1BBswOAP3kg3H1O4hiS+sq4YyAn6ANnA==} + engines: {node: '>= 6.11.5'} + hasBin: true + peerDependencies: + webpack: ^4.0.0 || ^5.0.0 + webpack-cli: '*' + peerDependenciesMeta: + webpack-cli: + optional: true + + webpack-log@2.0.0: + resolution: {integrity: sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==} + engines: {node: '>= 6'} + + webpack-merge@4.2.2: + resolution: {integrity: sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==} + + webpack-sources@1.4.3: + resolution: {integrity: sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==} + + webpack@4.47.0: + resolution: {integrity: sha512-td7fYwgLSrky3fI1EuU5cneU4+pbH6GgOfuKNS1tNPcfdGinGELAqsb/BP4nnvZyKSG2i/xFGU7+n2PvZA8HJQ==} + engines: {node: '>=6.11.5'} + hasBin: true + peerDependencies: + webpack-cli: '*' + webpack-command: '*' + peerDependenciesMeta: + webpack-cli: + optional: true + webpack-command: + optional: true + + websocket-driver@0.7.4: + resolution: {integrity: sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==} + engines: {node: '>=0.8.0'} + + websocket-extensions@0.1.4: + resolution: {integrity: sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==} + engines: {node: '>=0.8.0'} + + which-boxed-primitive@1.1.1: + resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} + engines: {node: '>= 0.4'} + + which-builtin-type@1.2.1: + resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} + engines: {node: '>= 0.4'} + + which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.4'} + + which-module@2.0.1: + resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} + + which-typed-array@1.1.20: + resolution: {integrity: sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==} + engines: {node: '>= 0.4'} + + which@1.3.1: + resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} + hasBin: true + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + worker-farm@1.7.0: + resolution: {integrity: sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==} + + wrap-ansi@5.1.0: + resolution: {integrity: sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==} + engines: {node: '>=6'} + + wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + ws@6.2.3: + resolution: {integrity: sha512-jmTjYU0j60B+vHey6TfR3Z7RD61z/hmxBS3VMSGIrroOWXQEneK1zNuotOUrGyBHQj0yrpsLHPWtigEFd13ndA==} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + + y18n@4.0.3: + resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yallist@2.1.2: + resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + + yaml@1.10.3: + resolution: {integrity: sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA==} + engines: {node: '>= 6'} + + yargs-parser@13.1.2: + resolution: {integrity: sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==} + + yargs-parser@20.2.9: + resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} + engines: {node: '>=10'} + + yargs@13.3.2: + resolution: {integrity: sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==} + + yargs@16.2.0: + resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} + engines: {node: '>=10'} + + yorkie@2.0.0: + resolution: {integrity: sha512-jcKpkthap6x63MB4TxwCyuIGkV0oYP/YRyuQU5UO0Yz/E/ZAu+653/uov+phdmO54n6BcvFRyyt0RRrWdN2mpw==} + engines: {node: '>=4'} + + zrender@5.4.0: + resolution: {integrity: sha512-rOS09Z2HSVGFs2dn/TuYk5BlCaZcVe8UDLLjj1ySYF828LATKKdxuakSZMvrDz54yiKPDYVfjdKqcX8Jky3BIA==} + +snapshots: + + '@achrinza/node-ipc@9.2.2': + dependencies: + '@node-ipc/js-queue': 2.0.3 + event-pubsub: 4.3.0 + js-message: 1.0.7 + + '@babel/code-frame@7.29.0': + dependencies: + '@babel/helper-validator-identifier': 7.28.5 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.29.0': {} + + '@babel/core@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helpers': 7.29.2 + '@babel/parser': 7.29.2 + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3(supports-color@6.1.0) + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.29.1': + dependencies: + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/helper-annotate-as-pure@7.27.3': + dependencies: + '@babel/types': 7.29.0 + + '@babel/helper-compilation-targets@7.28.6': + dependencies: + '@babel/compat-data': 7.29.0 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.28.2 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-create-class-features-plugin@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-member-expression-to-functions': 7.28.5 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/traverse': 7.29.0 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-create-regexp-features-plugin@7.28.5(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + regexpu-core: 6.4.0 + semver: 6.3.1 + + '@babel/helper-define-polyfill-provider@0.6.8(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + debug: 4.4.3(supports-color@6.1.0) + lodash.debounce: 4.0.8 + resolve: 1.22.12 + transitivePeerDependencies: + - supports-color + + '@babel/helper-globals@7.28.0': {} + + '@babel/helper-member-expression-to-functions@7.28.5': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-imports@7.28.6': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-optimise-call-expression@7.27.1': + dependencies: + '@babel/types': 7.29.0 + + '@babel/helper-plugin-utils@7.28.6': {} + + '@babel/helper-remap-async-to-generator@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-wrap-function': 7.28.6 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-replace-supers@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-member-expression-to-functions': 7.28.5 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.28.5': {} + + '@babel/helper-validator-option@7.27.1': {} + + '@babel/helper-wrap-function@7.28.6': + dependencies: + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helpers@7.29.2': + dependencies: + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + + '@babel/parser@7.29.2': + dependencies: + '@babel/types': 7.29.0 + + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/plugin-transform-optional-chaining': 7.28.6(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-proposal-class-properties@7.18.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-proposal-decorators@7.29.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-syntax-decorators': 7.28.6(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + + '@babel/plugin-syntax-decorators@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-import-assertions@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-import-attributes@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-async-generator-functions@7.29.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.29.0) + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-async-to-generator@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-block-scoped-functions@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-block-scoping@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-class-properties@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-class-static-block@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-classes@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-globals': 7.28.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-computed-properties@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/template': 7.28.6 + + '@babel/plugin-transform-destructuring@7.28.5(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-dotall-regex@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-duplicate-keys@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.29.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-dynamic-import@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-explicit-resource-management@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-exponentiation-operator@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-export-namespace-from@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-for-of@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-function-name@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-json-strings@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-literals@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-logical-assignment-operators@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-member-expression-literals@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-modules-amd@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-commonjs@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-systemjs@7.29.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-umd@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-named-capturing-groups-regex@7.29.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-new-target@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-nullish-coalescing-operator@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-numeric-separator@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-object-rest-spread@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.29.0) + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-object-super@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-optional-catch-binding@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-optional-chaining@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-parameters@7.27.7(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-private-methods@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-private-property-in-object@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-property-literals@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-regenerator@7.29.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-regexp-modifiers@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-reserved-words@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-runtime@7.29.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + babel-plugin-polyfill-corejs2: 0.4.17(@babel/core@7.29.0) + babel-plugin-polyfill-corejs3: 0.13.0(@babel/core@7.29.0) + babel-plugin-polyfill-regenerator: 0.6.8(@babel/core@7.29.0) + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-shorthand-properties@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-spread@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-sticky-regex@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-template-literals@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-typeof-symbol@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-unicode-escapes@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-unicode-property-regex@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-unicode-regex@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-unicode-sets-regex@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/preset-env@7.29.2(@babel/core@7.29.0)': + dependencies: + '@babel/compat-data': 7.29.0 + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-validator-option': 7.27.1 + '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.28.5(@babel/core@7.29.0) + '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.29.0) + '@babel/plugin-syntax-import-assertions': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-syntax-import-attributes': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.29.0) + '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-async-generator-functions': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-async-to-generator': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-block-scoped-functions': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-block-scoping': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-class-properties': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-class-static-block': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-classes': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-computed-properties': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0) + '@babel/plugin-transform-dotall-regex': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-duplicate-keys': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-dynamic-import': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-explicit-resource-management': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-exponentiation-operator': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-export-namespace-from': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-for-of': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-function-name': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-json-strings': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-literals': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-logical-assignment-operators': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-member-expression-literals': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-modules-amd': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-modules-systemjs': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-modules-umd': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-named-capturing-groups-regex': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-new-target': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-nullish-coalescing-operator': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-numeric-separator': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-object-rest-spread': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-object-super': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-optional-catch-binding': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-optional-chaining': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.29.0) + '@babel/plugin-transform-private-methods': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-private-property-in-object': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-property-literals': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-regenerator': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-regexp-modifiers': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-reserved-words': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-spread': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-sticky-regex': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-template-literals': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-typeof-symbol': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-unicode-escapes': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-unicode-property-regex': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-unicode-regex': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-unicode-sets-regex': 7.28.6(@babel/core@7.29.0) + '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.29.0) + babel-plugin-polyfill-corejs2: 0.4.17(@babel/core@7.29.0) + babel-plugin-polyfill-corejs3: 0.14.2(@babel/core@7.29.0) + babel-plugin-polyfill-regenerator: 0.6.8(@babel/core@7.29.0) + core-js-compat: 3.49.0 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/types': 7.29.0 + esutils: 2.0.3 + + '@babel/runtime@7.29.2': {} + + '@babel/template@7.28.6': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 + + '@babel/traverse@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.29.2 + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + debug: 4.4.3(supports-color@6.1.0) + transitivePeerDependencies: + - supports-color + + '@babel/types@7.29.0': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + + '@eslint/eslintrc@0.2.2': + dependencies: + ajv: 6.15.0 + debug: 4.4.3(supports-color@6.1.0) + espree: 7.3.1 + globals: 12.4.0 + ignore: 4.0.6 + import-fresh: 3.3.1 + js-yaml: 3.14.2 + lodash: 4.18.1 + minimatch: 3.1.5 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@gar/promisify@1.1.3': {} + + '@hapi/address@2.1.4': {} + + '@hapi/bourne@1.3.2': {} + + '@hapi/hoek@8.5.1': {} + + '@hapi/joi@15.1.1': + dependencies: + '@hapi/address': 2.1.4 + '@hapi/bourne': 1.3.2 + '@hapi/hoek': 8.5.1 + '@hapi/topo': 3.1.6 + + '@hapi/topo@3.1.6': + dependencies: + '@hapi/hoek': 8.5.1 + + '@intervolga/optimize-cssnano-plugin@1.0.6(webpack@4.47.0)': + dependencies: + cssnano: 4.1.11 + cssnano-preset-default: 4.0.8 + postcss: 7.0.39 + webpack: 4.47.0 + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@leichtgewicht/ip-codec@2.0.5': {} + + '@mrmlnc/readdir-enhanced@2.2.1': + dependencies: + call-me-maybe: 1.0.2 + glob-to-regexp: 0.3.0 + + '@node-ipc/js-queue@2.0.3': + dependencies: + easy-stack: 1.0.1 + + '@nodelib/fs.stat@1.1.3': {} + + '@npmcli/fs@1.1.1': + dependencies: + '@gar/promisify': 1.1.3 + semver: 7.7.4 + + '@npmcli/move-file@1.1.2': + dependencies: + mkdirp: 1.0.4 + rimraf: 3.0.2 + + '@riophae/vue-treeselect@0.4.0(vue@2.6.12)': + dependencies: + '@babel/runtime': 7.29.2 + babel-helper-vue-jsx-merge-props: 2.0.3 + easings-css: 1.0.0 + fuzzysearch: 1.0.3 + is-promise: 2.2.2 + lodash: 4.18.1 + material-colors: 1.2.6 + vue: 2.6.12 + watch-size: 2.0.0 + + '@soda/friendly-errors-webpack-plugin@1.8.1(webpack@4.47.0)': + dependencies: + chalk: 3.0.0 + error-stack-parser: 2.1.4 + string-width: 4.2.3 + strip-ansi: 6.0.1 + webpack: 4.47.0 + + '@soda/get-current-script@1.0.2': {} + + '@types/glob@7.2.0': + dependencies: + '@types/minimatch': 6.0.0 + '@types/node': 25.6.0 + + '@types/json-schema@7.0.15': {} + + '@types/minimatch@6.0.0': + dependencies: + minimatch: 10.2.5 + + '@types/node@25.6.0': + dependencies: + undici-types: 7.19.2 + + '@types/normalize-package-data@2.4.4': {} + + '@types/parse-json@4.0.2': {} + + '@types/q@1.5.8': {} + + '@vue/babel-helper-vue-jsx-merge-props@1.4.0': {} + + '@vue/babel-helper-vue-transform-on@1.5.0': {} + + '@vue/babel-plugin-jsx@1.5.0(@babel/core@7.29.0)': + dependencies: + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + '@vue/babel-helper-vue-transform-on': 1.5.0 + '@vue/babel-plugin-resolve-type': 1.5.0(@babel/core@7.29.0) + '@vue/shared': 3.5.33 + optionalDependencies: + '@babel/core': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@vue/babel-plugin-resolve-type@1.5.0(@babel/core@7.29.0)': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/parser': 7.29.2 + '@vue/compiler-sfc': 3.5.33 + transitivePeerDependencies: + - supports-color + + '@vue/babel-plugin-transform-vue-jsx@1.4.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + '@vue/babel-helper-vue-jsx-merge-props': 1.4.0 + html-tags: 2.0.0 + lodash.kebabcase: 4.1.1 + svg-tags: 1.0.0 + transitivePeerDependencies: + - supports-color + + '@vue/babel-preset-app@4.5.19(@babel/core@7.29.0)(core-js@3.37.1)(vue@2.6.12)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-module-imports': 7.28.6 + '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.29.0) + '@babel/plugin-proposal-decorators': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.29.0) + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-runtime': 7.29.0(@babel/core@7.29.0) + '@babel/preset-env': 7.29.2(@babel/core@7.29.0) + '@babel/runtime': 7.29.2 + '@vue/babel-plugin-jsx': 1.5.0(@babel/core@7.29.0) + '@vue/babel-preset-jsx': 1.4.0(@babel/core@7.29.0)(vue@2.6.12) + babel-plugin-dynamic-import-node: 2.3.3 + core-js-compat: 3.49.0 + semver: 6.3.1 + optionalDependencies: + core-js: 3.37.1 + vue: 2.6.12 + transitivePeerDependencies: + - supports-color + + '@vue/babel-preset-jsx@1.4.0(@babel/core@7.29.0)(vue@2.6.12)': + dependencies: + '@babel/core': 7.29.0 + '@vue/babel-helper-vue-jsx-merge-props': 1.4.0 + '@vue/babel-plugin-transform-vue-jsx': 1.4.0(@babel/core@7.29.0) + '@vue/babel-sugar-composition-api-inject-h': 1.4.0(@babel/core@7.29.0) + '@vue/babel-sugar-composition-api-render-instance': 1.4.0(@babel/core@7.29.0) + '@vue/babel-sugar-functional-vue': 1.4.0(@babel/core@7.29.0) + '@vue/babel-sugar-inject-h': 1.4.0(@babel/core@7.29.0) + '@vue/babel-sugar-v-model': 1.4.0(@babel/core@7.29.0) + '@vue/babel-sugar-v-on': 1.4.0(@babel/core@7.29.0) + optionalDependencies: + vue: 2.6.12 + transitivePeerDependencies: + - supports-color + + '@vue/babel-sugar-composition-api-inject-h@1.4.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + + '@vue/babel-sugar-composition-api-render-instance@1.4.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + + '@vue/babel-sugar-functional-vue@1.4.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + + '@vue/babel-sugar-inject-h@1.4.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + + '@vue/babel-sugar-v-model@1.4.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + '@vue/babel-helper-vue-jsx-merge-props': 1.4.0 + '@vue/babel-plugin-transform-vue-jsx': 1.4.0(@babel/core@7.29.0) + camelcase: 5.3.1 + html-tags: 2.0.0 + svg-tags: 1.0.0 + transitivePeerDependencies: + - supports-color + + '@vue/babel-sugar-v-on@1.4.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + '@vue/babel-plugin-transform-vue-jsx': 1.4.0(@babel/core@7.29.0) + camelcase: 5.3.1 + transitivePeerDependencies: + - supports-color + + '@vue/cli-overlay@4.5.19': {} + + '@vue/cli-plugin-babel@4.4.6(@vue/cli-service@4.4.6(@vue/compiler-sfc@3.5.33)(lodash@4.18.1)(sass-loader@10.1.1(sass@1.32.13)(webpack@4.47.0))(vue-template-compiler@2.6.12))(core-js@3.37.1)(vue@2.6.12)': + dependencies: + '@babel/core': 7.29.0 + '@vue/babel-preset-app': 4.5.19(@babel/core@7.29.0)(core-js@3.37.1)(vue@2.6.12) + '@vue/cli-service': 4.4.6(@vue/compiler-sfc@3.5.33)(lodash@4.18.1)(sass-loader@10.1.1(sass@1.32.13)(webpack@4.47.0))(vue-template-compiler@2.6.12) + '@vue/cli-shared-utils': 4.5.19 + babel-loader: 8.4.1(@babel/core@7.29.0)(webpack@4.47.0) + cache-loader: 4.1.0(webpack@4.47.0) + thread-loader: 2.1.3(webpack@4.47.0) + webpack: 4.47.0 + transitivePeerDependencies: + - core-js + - supports-color + - vue + - webpack-cli + - webpack-command + + '@vue/cli-plugin-eslint@4.4.6(@vue/cli-service@4.4.6(@vue/compiler-sfc@3.5.33)(lodash@4.18.1)(sass-loader@10.1.1(sass@1.32.13)(webpack@4.47.0))(vue-template-compiler@2.6.12))(eslint@7.15.0)': + dependencies: + '@vue/cli-service': 4.4.6(@vue/compiler-sfc@3.5.33)(lodash@4.18.1)(sass-loader@10.1.1(sass@1.32.13)(webpack@4.47.0))(vue-template-compiler@2.6.12) + '@vue/cli-shared-utils': 4.5.19 + eslint: 7.15.0 + eslint-loader: 2.2.1(eslint@7.15.0)(webpack@4.47.0) + globby: 9.2.0 + inquirer: 7.3.3 + webpack: 4.47.0 + yorkie: 2.0.0 + transitivePeerDependencies: + - supports-color + - webpack-cli + - webpack-command + + '@vue/cli-plugin-router@4.5.19(@vue/cli-service@4.4.6(@vue/compiler-sfc@3.5.33)(lodash@4.18.1)(sass-loader@10.1.1(sass@1.32.13)(webpack@4.47.0))(vue-template-compiler@2.6.12))': + dependencies: + '@vue/cli-service': 4.4.6(@vue/compiler-sfc@3.5.33)(lodash@4.18.1)(sass-loader@10.1.1(sass@1.32.13)(webpack@4.47.0))(vue-template-compiler@2.6.12) + '@vue/cli-shared-utils': 4.5.19 + + '@vue/cli-plugin-vuex@4.5.19(@vue/cli-service@4.4.6(@vue/compiler-sfc@3.5.33)(lodash@4.18.1)(sass-loader@10.1.1(sass@1.32.13)(webpack@4.47.0))(vue-template-compiler@2.6.12))': + dependencies: + '@vue/cli-service': 4.4.6(@vue/compiler-sfc@3.5.33)(lodash@4.18.1)(sass-loader@10.1.1(sass@1.32.13)(webpack@4.47.0))(vue-template-compiler@2.6.12) + + '@vue/cli-service@4.4.6(@vue/compiler-sfc@3.5.33)(lodash@4.18.1)(sass-loader@10.1.1(sass@1.32.13)(webpack@4.47.0))(vue-template-compiler@2.6.12)': + dependencies: + '@intervolga/optimize-cssnano-plugin': 1.0.6(webpack@4.47.0) + '@soda/friendly-errors-webpack-plugin': 1.8.1(webpack@4.47.0) + '@soda/get-current-script': 1.0.2 + '@vue/cli-overlay': 4.5.19 + '@vue/cli-plugin-router': 4.5.19(@vue/cli-service@4.4.6(@vue/compiler-sfc@3.5.33)(lodash@4.18.1)(sass-loader@10.1.1(sass@1.32.13)(webpack@4.47.0))(vue-template-compiler@2.6.12)) + '@vue/cli-plugin-vuex': 4.5.19(@vue/cli-service@4.4.6(@vue/compiler-sfc@3.5.33)(lodash@4.18.1)(sass-loader@10.1.1(sass@1.32.13)(webpack@4.47.0))(vue-template-compiler@2.6.12)) + '@vue/cli-shared-utils': 4.5.19 + '@vue/component-compiler-utils': 3.3.0(lodash@4.18.1) + '@vue/preload-webpack-plugin': 1.1.2(html-webpack-plugin@3.2.0(webpack@4.47.0))(webpack@4.47.0) + '@vue/web-component-wrapper': 1.3.0 + acorn: 7.4.1 + acorn-walk: 7.2.0 + address: 1.2.2 + autoprefixer: 9.8.8 + browserslist: 4.28.2 + cache-loader: 4.1.0(webpack@4.47.0) + case-sensitive-paths-webpack-plugin: 2.4.0 + cli-highlight: 2.1.11 + clipboardy: 2.3.0 + cliui: 6.0.0 + copy-webpack-plugin: 5.1.2(webpack@4.47.0) + css-loader: 3.6.0(webpack@4.47.0) + cssnano: 4.1.11 + debug: 4.4.3(supports-color@6.1.0) + default-gateway: 5.0.5 + dotenv: 8.6.0 + dotenv-expand: 5.1.0 + file-loader: 4.3.0(webpack@4.47.0) + fs-extra: 7.0.1 + globby: 9.2.0 + hash-sum: 2.0.0 + html-webpack-plugin: 3.2.0(webpack@4.47.0) + launch-editor-middleware: 2.13.2 + lodash.defaultsdeep: 4.6.1 + lodash.mapvalues: 4.6.0 + lodash.transform: 4.6.0 + mini-css-extract-plugin: 0.9.0(webpack@4.47.0) + minimist: 1.2.8 + pnp-webpack-plugin: 1.7.0 + portfinder: 1.0.38(supports-color@6.1.0) + postcss-loader: 3.0.0 + ssri: 7.1.1 + terser-webpack-plugin: 2.3.8(webpack@4.47.0) + thread-loader: 2.1.3(webpack@4.47.0) + url-loader: 2.3.0(file-loader@4.3.0(webpack@4.47.0))(webpack@4.47.0) + vue-loader: 15.11.1(@vue/compiler-sfc@3.5.33)(cache-loader@4.1.0(webpack@4.47.0))(css-loader@3.6.0(webpack@4.47.0))(lodash@4.18.1)(vue-template-compiler@2.6.12)(webpack@4.47.0) + vue-style-loader: 4.1.3 + webpack: 4.47.0 + webpack-bundle-analyzer: 3.9.0 + webpack-chain: 6.5.1 + webpack-dev-server: 3.11.3(webpack@4.47.0) + webpack-merge: 4.2.2 + optionalDependencies: + sass-loader: 10.1.1(sass@1.32.13)(webpack@4.47.0) + vue-template-compiler: 2.6.12 + transitivePeerDependencies: + - '@vue/compiler-sfc' + - arc-templates + - atpl + - babel-core + - bluebird + - bracket-template + - bufferutil + - coffee-script + - dot + - dust + - dustjs-helpers + - dustjs-linkedin + - eco + - ect + - ejs + - haml-coffee + - hamlet + - hamljs + - handlebars + - hogan.js + - htmling + - jade + - jazz + - jqtpl + - just + - liquid-node + - liquor + - lodash + - marko + - mote + - mustache + - nunjucks + - plates + - prettier + - pug + - qejs + - ractive + - razor-tmpl + - react + - react-dom + - slm + - squirrelly + - supports-color + - swig + - swig-templates + - teacup + - templayed + - then-jade + - then-pug + - tinyliquid + - toffee + - twig + - twing + - typescript + - underscore + - utf-8-validate + - vash + - velocityjs + - walrus + - webpack-cli + - webpack-command + - whiskers + + '@vue/cli-shared-utils@4.5.19': + dependencies: + '@achrinza/node-ipc': 9.2.2 + '@hapi/joi': 15.1.1 + chalk: 2.4.2 + execa: 1.0.0 + launch-editor: 2.13.2 + lru-cache: 5.1.1 + open: 6.4.0 + ora: 3.4.0 + read-pkg: 5.2.0 + request: 2.88.2 + semver: 6.3.1 + strip-ansi: 6.0.1 + + '@vue/compiler-core@3.5.33': + dependencies: + '@babel/parser': 7.29.2 + '@vue/shared': 3.5.33 + entities: 7.0.1 + estree-walker: 2.0.2 + source-map-js: 1.2.1 + + '@vue/compiler-dom@3.5.33': + dependencies: + '@vue/compiler-core': 3.5.33 + '@vue/shared': 3.5.33 + + '@vue/compiler-sfc@3.5.33': + dependencies: + '@babel/parser': 7.29.2 + '@vue/compiler-core': 3.5.33 + '@vue/compiler-dom': 3.5.33 + '@vue/compiler-ssr': 3.5.33 + '@vue/shared': 3.5.33 + estree-walker: 2.0.2 + magic-string: 0.30.21 + postcss: 8.5.10 + source-map-js: 1.2.1 + + '@vue/compiler-ssr@3.5.33': + dependencies: + '@vue/compiler-dom': 3.5.33 + '@vue/shared': 3.5.33 + + '@vue/component-compiler-utils@3.3.0(lodash@4.18.1)': + dependencies: + consolidate: 0.15.1(lodash@4.18.1) + hash-sum: 1.0.2 + lru-cache: 4.1.5 + merge-source-map: 1.1.0 + postcss: 7.0.39 + postcss-selector-parser: 6.1.2 + source-map: 0.6.1 + vue-template-es2015-compiler: 1.9.1 + optionalDependencies: + prettier: 2.8.8 + transitivePeerDependencies: + - arc-templates + - atpl + - babel-core + - bracket-template + - coffee-script + - dot + - dust + - dustjs-helpers + - dustjs-linkedin + - eco + - ect + - ejs + - haml-coffee + - hamlet + - hamljs + - handlebars + - hogan.js + - htmling + - jade + - jazz + - jqtpl + - just + - liquid-node + - liquor + - lodash + - marko + - mote + - mustache + - nunjucks + - plates + - pug + - qejs + - ractive + - razor-tmpl + - react + - react-dom + - slm + - squirrelly + - swig + - swig-templates + - teacup + - templayed + - then-jade + - then-pug + - tinyliquid + - toffee + - twig + - twing + - underscore + - vash + - velocityjs + - walrus + - whiskers + + '@vue/preload-webpack-plugin@1.1.2(html-webpack-plugin@3.2.0(webpack@4.47.0))(webpack@4.47.0)': + dependencies: + html-webpack-plugin: 3.2.0(webpack@4.47.0) + webpack: 4.47.0 + + '@vue/shared@3.5.33': {} + + '@vue/web-component-wrapper@1.3.0': {} + + '@webassemblyjs/ast@1.9.0': + dependencies: + '@webassemblyjs/helper-module-context': 1.9.0 + '@webassemblyjs/helper-wasm-bytecode': 1.9.0 + '@webassemblyjs/wast-parser': 1.9.0 + + '@webassemblyjs/floating-point-hex-parser@1.9.0': {} + + '@webassemblyjs/helper-api-error@1.9.0': {} + + '@webassemblyjs/helper-buffer@1.9.0': {} + + '@webassemblyjs/helper-code-frame@1.9.0': + dependencies: + '@webassemblyjs/wast-printer': 1.9.0 + + '@webassemblyjs/helper-fsm@1.9.0': {} + + '@webassemblyjs/helper-module-context@1.9.0': + dependencies: + '@webassemblyjs/ast': 1.9.0 + + '@webassemblyjs/helper-wasm-bytecode@1.9.0': {} + + '@webassemblyjs/helper-wasm-section@1.9.0': + dependencies: + '@webassemblyjs/ast': 1.9.0 + '@webassemblyjs/helper-buffer': 1.9.0 + '@webassemblyjs/helper-wasm-bytecode': 1.9.0 + '@webassemblyjs/wasm-gen': 1.9.0 + + '@webassemblyjs/ieee754@1.9.0': + dependencies: + '@xtuc/ieee754': 1.2.0 + + '@webassemblyjs/leb128@1.9.0': + dependencies: + '@xtuc/long': 4.2.2 + + '@webassemblyjs/utf8@1.9.0': {} + + '@webassemblyjs/wasm-edit@1.9.0': + dependencies: + '@webassemblyjs/ast': 1.9.0 + '@webassemblyjs/helper-buffer': 1.9.0 + '@webassemblyjs/helper-wasm-bytecode': 1.9.0 + '@webassemblyjs/helper-wasm-section': 1.9.0 + '@webassemblyjs/wasm-gen': 1.9.0 + '@webassemblyjs/wasm-opt': 1.9.0 + '@webassemblyjs/wasm-parser': 1.9.0 + '@webassemblyjs/wast-printer': 1.9.0 + + '@webassemblyjs/wasm-gen@1.9.0': + dependencies: + '@webassemblyjs/ast': 1.9.0 + '@webassemblyjs/helper-wasm-bytecode': 1.9.0 + '@webassemblyjs/ieee754': 1.9.0 + '@webassemblyjs/leb128': 1.9.0 + '@webassemblyjs/utf8': 1.9.0 + + '@webassemblyjs/wasm-opt@1.9.0': + dependencies: + '@webassemblyjs/ast': 1.9.0 + '@webassemblyjs/helper-buffer': 1.9.0 + '@webassemblyjs/wasm-gen': 1.9.0 + '@webassemblyjs/wasm-parser': 1.9.0 + + '@webassemblyjs/wasm-parser@1.9.0': + dependencies: + '@webassemblyjs/ast': 1.9.0 + '@webassemblyjs/helper-api-error': 1.9.0 + '@webassemblyjs/helper-wasm-bytecode': 1.9.0 + '@webassemblyjs/ieee754': 1.9.0 + '@webassemblyjs/leb128': 1.9.0 + '@webassemblyjs/utf8': 1.9.0 + + '@webassemblyjs/wast-parser@1.9.0': + dependencies: + '@webassemblyjs/ast': 1.9.0 + '@webassemblyjs/floating-point-hex-parser': 1.9.0 + '@webassemblyjs/helper-api-error': 1.9.0 + '@webassemblyjs/helper-code-frame': 1.9.0 + '@webassemblyjs/helper-fsm': 1.9.0 + '@xtuc/long': 4.2.2 + + '@webassemblyjs/wast-printer@1.9.0': + dependencies: + '@webassemblyjs/ast': 1.9.0 + '@webassemblyjs/wast-parser': 1.9.0 + '@xtuc/long': 4.2.2 + + '@xtuc/ieee754@1.2.0': {} + + '@xtuc/long@4.2.2': {} + + abbrev@1.1.1: {} + + accepts@1.3.8: + dependencies: + mime-types: 2.1.35 + negotiator: 0.6.3 + + acorn-jsx@5.3.2(acorn@7.4.1): + dependencies: + acorn: 7.4.1 + + acorn-walk@7.2.0: {} + + acorn@6.4.2: {} + + acorn@7.4.1: {} + + acorn@8.16.0: {} + + address@1.2.2: {} + + aggregate-error@3.1.0: + dependencies: + clean-stack: 2.2.0 + indent-string: 4.0.0 + + ajv-errors@1.0.1(ajv@6.15.0): + dependencies: + ajv: 6.15.0 + + ajv-keywords@3.5.2(ajv@6.15.0): + dependencies: + ajv: 6.15.0 + + ajv@6.15.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + alphanum-sort@1.0.2: {} + + ansi-colors@3.2.4: {} + + ansi-colors@4.1.3: {} + + ansi-escapes@4.3.2: + dependencies: + type-fest: 0.21.3 + + ansi-html-community@0.0.8: {} + + ansi-regex@2.1.1: {} + + ansi-regex@4.1.1: {} + + ansi-regex@5.0.1: {} + + ansi-styles@2.2.1: {} + + ansi-styles@3.2.1: + dependencies: + color-convert: 1.9.3 + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + any-promise@1.3.0: {} + + anymatch@2.0.0(supports-color@6.1.0): + dependencies: + micromatch: 3.1.10(supports-color@6.1.0) + normalize-path: 2.1.1 + transitivePeerDependencies: + - supports-color + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.2 + + aproba@1.2.0: {} + + arch@2.2.0: {} + + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + + arr-diff@4.0.0: {} + + arr-flatten@1.1.0: {} + + arr-union@3.1.0: {} + + array-buffer-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + is-array-buffer: 3.0.5 + + array-flatten@1.1.1: {} + + array-flatten@2.1.2: {} + + array-union@1.0.2: + dependencies: + array-uniq: 1.0.3 + + array-uniq@1.0.3: {} + + array-unique@0.3.2: {} + + array.prototype.reduce@1.0.8: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-array-method-boxes-properly: 1.0.0 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + is-string: 1.1.1 + + arraybuffer.prototype.slice@1.0.4: + dependencies: + array-buffer-byte-length: 1.0.2 + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + is-array-buffer: 3.0.5 + + asn1.js@4.10.1: + dependencies: + bn.js: 4.12.3 + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + + asn1@0.2.6: + dependencies: + safer-buffer: 2.1.2 + + assert-plus@1.0.0: {} + + assert@1.5.1: + dependencies: + object.assign: 4.1.7 + util: 0.10.4 + + assign-symbols@1.0.0: {} + + astral-regex@1.0.0: {} + + astral-regex@2.0.0: {} + + async-each@1.0.6: {} + + async-function@1.0.0: {} + + async-limiter@1.0.1: {} + + async-validator@1.8.5: + dependencies: + babel-runtime: 6.26.0 + + async@3.2.6: {} + + asynckit@0.4.0: {} + + atob@2.1.2: {} + + autoprefixer@9.8.8: + dependencies: + browserslist: 4.28.2 + caniuse-lite: 1.0.30001790 + normalize-range: 0.1.2 + num2fraction: 1.2.2 + picocolors: 0.2.1 + postcss: 7.0.39 + postcss-value-parser: 4.2.0 + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.1.0 + + aws-sign2@0.7.0: {} + + aws4@1.13.2: {} + + axios@0.28.1: + dependencies: + follow-redirects: 1.16.0(debug@4.4.3) + form-data: 4.0.5 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + + babel-eslint@10.1.0(eslint@7.15.0): + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/parser': 7.29.2 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + eslint: 7.15.0 + eslint-visitor-keys: 1.3.0 + resolve: 1.22.12 + transitivePeerDependencies: + - supports-color + + babel-helper-vue-jsx-merge-props@2.0.3: {} + + babel-loader@8.4.1(@babel/core@7.29.0)(webpack@4.47.0): + dependencies: + '@babel/core': 7.29.0 + find-cache-dir: 3.3.2 + loader-utils: 2.0.4 + make-dir: 3.1.0 + schema-utils: 2.7.1 + webpack: 4.47.0 + + babel-plugin-dynamic-import-node@2.3.3: + dependencies: + object.assign: 4.1.7 + + babel-plugin-polyfill-corejs2@0.4.17(@babel/core@7.29.0): + dependencies: + '@babel/compat-data': 7.29.0 + '@babel/core': 7.29.0 + '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.0) + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + babel-plugin-polyfill-corejs3@0.13.0(@babel/core@7.29.0): + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.0) + core-js-compat: 3.49.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-polyfill-corejs3@0.14.2(@babel/core@7.29.0): + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.0) + core-js-compat: 3.49.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-polyfill-regenerator@0.6.8(@babel/core@7.29.0): + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + babel-runtime@6.26.0: + dependencies: + core-js: 2.6.12 + regenerator-runtime: 0.11.1 + + balanced-match@1.0.2: {} + + balanced-match@4.0.4: {} + + base64-js@1.5.1: {} + + base@0.11.2: + dependencies: + cache-base: 1.0.1 + class-utils: 0.3.6 + component-emitter: 1.3.1 + define-property: 1.0.0 + isobject: 3.0.1 + mixin-deep: 1.3.2 + pascalcase: 0.1.1 + + baseline-browser-mapping@2.10.22: {} + + batch@0.6.1: {} + + bcrypt-pbkdf@1.0.2: + dependencies: + tweetnacl: 0.14.5 + + bfj@6.1.2: + dependencies: + bluebird: 3.7.2 + check-types: 8.0.3 + hoopy: 0.1.4 + tryer: 1.0.1 + + big.js@3.2.0: {} + + big.js@5.2.2: {} + + binary-extensions@1.13.1: {} + + binary-extensions@2.3.0: {} + + bindings@1.5.0: + dependencies: + file-uri-to-path: 1.0.0 + optional: true + + bluebird@3.7.2: {} + + bn.js@4.12.3: {} + + bn.js@5.2.3: {} + + body-parser@1.20.5(supports-color@6.1.0): + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 2.6.9(supports-color@6.1.0) + depd: 2.0.0 + destroy: 1.2.0 + http-errors: 2.0.1 + iconv-lite: 0.4.24 + on-finished: 2.4.1 + qs: 6.15.1 + raw-body: 2.5.3 + type-is: 1.6.18 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + bonjour@3.5.1: + dependencies: + array-flatten: 2.1.2 + deep-equal: 1.1.2 + dns-equal: 1.0.0 + dns-txt: 2.0.2 + multicast-dns: 7.2.5 + multicast-dns-service-types: 1.1.0 + + boolbase@1.0.0: {} + + brace-expansion@1.1.14: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@5.0.5: + dependencies: + balanced-match: 4.0.4 + + braces@2.3.2(supports-color@6.1.0): + dependencies: + arr-flatten: 1.1.0 + array-unique: 0.3.2 + extend-shallow: 2.0.1 + fill-range: 4.0.0 + isobject: 3.0.1 + repeat-element: 1.1.4 + snapdragon: 0.8.2(supports-color@6.1.0) + snapdragon-node: 2.1.1 + split-string: 3.1.0 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + brorand@1.1.0: {} + + browserify-aes@1.2.0: + dependencies: + buffer-xor: 1.0.3 + cipher-base: 1.0.7 + create-hash: 1.2.0 + evp_bytestokey: 1.0.3 + inherits: 2.0.4 + safe-buffer: 5.2.1 + + browserify-cipher@1.0.1: + dependencies: + browserify-aes: 1.2.0 + browserify-des: 1.0.2 + evp_bytestokey: 1.0.3 + + browserify-des@1.0.2: + dependencies: + cipher-base: 1.0.7 + des.js: 1.1.0 + inherits: 2.0.4 + safe-buffer: 5.2.1 + + browserify-rsa@4.1.1: + dependencies: + bn.js: 5.2.3 + randombytes: 2.1.0 + safe-buffer: 5.2.1 + + browserify-sign@4.2.5: + dependencies: + bn.js: 5.2.3 + browserify-rsa: 4.1.1 + create-hash: 1.2.0 + create-hmac: 1.1.7 + elliptic: 6.6.1 + inherits: 2.0.4 + parse-asn1: 5.1.9 + readable-stream: 2.3.8 + safe-buffer: 5.2.1 + + browserify-zlib@0.2.0: + dependencies: + pako: 1.0.11 + + browserslist@4.28.2: + dependencies: + baseline-browser-mapping: 2.10.22 + caniuse-lite: 1.0.30001790 + electron-to-chromium: 1.5.344 + node-releases: 2.0.38 + update-browserslist-db: 1.2.3(browserslist@4.28.2) + + buffer-from@1.1.2: {} + + buffer-indexof@1.1.1: {} + + buffer-json@2.0.0: {} + + buffer-xor@1.0.3: {} + + buffer@4.9.2: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + isarray: 1.0.0 + + builtin-status-codes@3.0.0: {} + + bytes@3.1.2: {} + + cacache@12.0.4: + dependencies: + bluebird: 3.7.2 + chownr: 1.1.4 + figgy-pudding: 3.5.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + infer-owner: 1.0.4 + lru-cache: 5.1.1 + mississippi: 3.0.0 + mkdirp: 0.5.6 + move-concurrently: 1.0.1 + promise-inflight: 1.0.1(bluebird@3.7.2) + rimraf: 2.7.1 + ssri: 6.0.2 + unique-filename: 1.1.1 + y18n: 4.0.3 + + cacache@13.0.1: + dependencies: + chownr: 1.1.4 + figgy-pudding: 3.5.2 + fs-minipass: 2.1.0 + glob: 7.2.3 + graceful-fs: 4.2.11 + infer-owner: 1.0.4 + lru-cache: 5.1.1 + minipass: 3.3.6 + minipass-collect: 1.0.2 + minipass-flush: 1.0.7 + minipass-pipeline: 1.2.4 + mkdirp: 0.5.6 + move-concurrently: 1.0.1 + p-map: 3.0.0 + promise-inflight: 1.0.1(bluebird@3.7.2) + rimraf: 2.7.1 + ssri: 7.1.1 + unique-filename: 1.1.1 + transitivePeerDependencies: + - bluebird + + cacache@15.3.0: + dependencies: + '@npmcli/fs': 1.1.1 + '@npmcli/move-file': 1.1.2 + chownr: 2.0.0 + fs-minipass: 2.1.0 + glob: 7.2.3 + infer-owner: 1.0.4 + lru-cache: 6.0.0 + minipass: 3.3.6 + minipass-collect: 1.0.2 + minipass-flush: 1.0.7 + minipass-pipeline: 1.2.4 + mkdirp: 1.0.4 + p-map: 4.0.0 + promise-inflight: 1.0.1(bluebird@3.7.2) + rimraf: 3.0.2 + ssri: 8.0.1 + tar: 6.2.1 + unique-filename: 1.1.1 + transitivePeerDependencies: + - bluebird + + cache-base@1.0.1: + dependencies: + collection-visit: 1.0.0 + component-emitter: 1.3.1 + get-value: 2.0.6 + has-value: 1.0.0 + isobject: 3.0.1 + set-value: 2.0.1 + to-object-path: 0.3.0 + union-value: 1.0.1 + unset-value: 1.0.0 + + cache-loader@4.1.0(webpack@4.47.0): + dependencies: + buffer-json: 2.0.0 + find-cache-dir: 3.3.2 + loader-utils: 1.4.2 + mkdirp: 0.5.6 + neo-async: 2.6.2 + schema-utils: 2.7.1 + webpack: 4.47.0 + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bind@1.0.9: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + get-intrinsic: 1.3.0 + set-function-length: 1.2.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + call-me-maybe@1.0.2: {} + + caller-callsite@2.0.0: + dependencies: + callsites: 2.0.0 + + caller-path@2.0.0: + dependencies: + caller-callsite: 2.0.0 + + callsites@2.0.0: {} + + callsites@3.1.0: {} + + camel-case@3.0.0: + dependencies: + no-case: 2.3.2 + upper-case: 1.1.3 + + camelcase@5.3.1: {} + + caniuse-api@3.0.0: + dependencies: + browserslist: 4.28.2 + caniuse-lite: 1.0.30001790 + lodash.memoize: 4.1.2 + lodash.uniq: 4.5.0 + + caniuse-lite@1.0.30001790: {} + + case-sensitive-paths-webpack-plugin@2.4.0: {} + + caseless@0.12.0: {} + + chalk@1.1.3: + dependencies: + ansi-styles: 2.2.1 + escape-string-regexp: 1.0.5 + has-ansi: 2.0.0 + strip-ansi: 3.0.1 + supports-color: 2.0.0 + + chalk@2.3.0: + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 4.5.0 + + chalk@2.4.2: + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + + chalk@3.0.0: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chalk@4.1.0: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chardet@0.7.0: {} + + check-types@8.0.3: {} + + chokidar@2.1.8(supports-color@6.1.0): + dependencies: + anymatch: 2.0.0(supports-color@6.1.0) + async-each: 1.0.6 + braces: 2.3.2(supports-color@6.1.0) + glob-parent: 3.1.0 + inherits: 2.0.4 + is-binary-path: 1.0.1 + is-glob: 4.0.3 + normalize-path: 3.0.0 + path-is-absolute: 1.0.1 + readdirp: 2.2.1(supports-color@6.1.0) + upath: 1.2.0 + optionalDependencies: + fsevents: 1.2.13 + transitivePeerDependencies: + - supports-color + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + chownr@1.1.4: {} + + chownr@2.0.0: {} + + chrome-trace-event@1.0.4: {} + + ci-info@1.6.0: {} + + cipher-base@1.0.7: + dependencies: + inherits: 2.0.4 + safe-buffer: 5.2.1 + to-buffer: 1.2.2 + + class-utils@0.3.6: + dependencies: + arr-union: 3.1.0 + define-property: 0.2.5 + isobject: 3.0.1 + static-extend: 0.1.2 + + clean-css@4.2.4: + dependencies: + source-map: 0.6.1 + + clean-stack@2.2.0: {} + + cli-cursor@2.1.0: + dependencies: + restore-cursor: 2.0.0 + + cli-cursor@3.1.0: + dependencies: + restore-cursor: 3.1.0 + + cli-highlight@2.1.11: + dependencies: + chalk: 4.1.0 + highlight.js: 10.7.3 + mz: 2.7.0 + parse5: 5.1.1 + parse5-htmlparser2-tree-adapter: 6.0.1 + yargs: 16.2.0 + + cli-spinners@2.9.2: {} + + cli-truncate@2.1.0: + dependencies: + slice-ansi: 3.0.0 + string-width: 4.2.3 + + cli-width@3.0.0: {} + + clipboard@2.0.8: + dependencies: + good-listener: 1.2.2 + select: 1.1.2 + tiny-emitter: 2.1.0 + + clipboardy@2.3.0: + dependencies: + arch: 2.2.0 + execa: 1.0.0 + is-wsl: 2.2.0 + + cliui@5.0.0: + dependencies: + string-width: 3.1.0 + strip-ansi: 5.2.0 + wrap-ansi: 5.1.0 + + cliui@6.0.0: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + + cliui@7.0.4: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + clone@1.0.4: {} + + clone@2.1.2: {} + + coa@2.0.2: + dependencies: + '@types/q': 1.5.8 + chalk: 2.4.2 + q: 1.5.1 + + collection-visit@1.0.0: + dependencies: + map-visit: 1.0.0 + object-visit: 1.0.1 + + color-convert@1.9.3: + dependencies: + color-name: 1.1.3 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.3: {} + + color-name@1.1.4: {} + + color-string@1.9.1: + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.4 + + color@3.2.1: + dependencies: + color-convert: 1.9.3 + color-string: 1.9.1 + + colorette@2.0.20: {} + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + commander@2.17.1: {} + + commander@2.19.0: {} + + commander@2.20.3: {} + + commander@6.2.1: {} + + commondir@1.0.1: {} + + component-emitter@1.3.1: {} + + compressible@2.0.18: + dependencies: + mime-db: 1.54.0 + + compression-webpack-plugin@6.1.2(webpack@4.47.0): + dependencies: + cacache: 15.3.0 + find-cache-dir: 3.3.2 + schema-utils: 3.3.0 + serialize-javascript: 5.0.1 + webpack: 4.47.0 + webpack-sources: 1.4.3 + transitivePeerDependencies: + - bluebird + + compression@1.8.1(supports-color@6.1.0): + dependencies: + bytes: 3.1.2 + compressible: 2.0.18 + debug: 2.6.9(supports-color@6.1.0) + negotiator: 0.6.4 + on-headers: 1.1.0 + safe-buffer: 5.2.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + concat-map@0.0.1: {} + + concat-stream@1.6.2: + dependencies: + buffer-from: 1.1.2 + inherits: 2.0.4 + readable-stream: 2.3.8 + typedarray: 0.0.6 + + config-chain@1.1.13: + dependencies: + ini: 1.3.8 + proto-list: 1.2.4 + + connect-history-api-fallback@1.6.0: {} + + connect@3.6.6: + dependencies: + debug: 2.6.9(supports-color@6.1.0) + finalhandler: 1.1.0 + parseurl: 1.3.3 + utils-merge: 1.0.1 + transitivePeerDependencies: + - supports-color + + console-browserify@1.2.0: {} + + consolidate@0.15.1(lodash@4.18.1): + dependencies: + bluebird: 3.7.2 + optionalDependencies: + lodash: 4.18.1 + + constants-browserify@1.0.0: {} + + content-disposition@0.5.4: + dependencies: + safe-buffer: 5.2.1 + + content-type@1.0.5: {} + + convert-source-map@2.0.0: {} + + cookie-signature@1.0.7: {} + + cookie@0.7.2: {} + + copy-concurrently@1.0.5: + dependencies: + aproba: 1.2.0 + fs-write-stream-atomic: 1.0.10 + iferr: 0.1.5 + mkdirp: 0.5.6 + rimraf: 2.7.1 + run-queue: 1.0.3 + + copy-descriptor@0.1.1: {} + + copy-webpack-plugin@5.1.2(webpack@4.47.0): + dependencies: + cacache: 12.0.4 + find-cache-dir: 2.1.0 + glob-parent: 3.1.0 + globby: 7.1.1 + is-glob: 4.0.3 + loader-utils: 1.4.2 + minimatch: 3.1.5 + normalize-path: 3.0.0 + p-limit: 2.3.0 + schema-utils: 1.0.0 + serialize-javascript: 4.0.0 + webpack: 4.47.0 + webpack-log: 2.0.0 + + core-js-compat@3.49.0: + dependencies: + browserslist: 4.28.2 + + core-js@2.6.12: {} + + core-js@3.37.1: {} + + core-util-is@1.0.2: {} + + core-util-is@1.0.3: {} + + cosmiconfig@5.2.1: + dependencies: + import-fresh: 2.0.0 + is-directory: 0.3.1 + js-yaml: 3.14.2 + parse-json: 4.0.0 + + cosmiconfig@7.1.0: + dependencies: + '@types/parse-json': 4.0.2 + import-fresh: 3.3.1 + parse-json: 5.2.0 + path-type: 4.0.0 + yaml: 1.10.3 + + create-ecdh@4.0.4: + dependencies: + bn.js: 4.12.3 + elliptic: 6.6.1 + + create-hash@1.2.0: + dependencies: + cipher-base: 1.0.7 + inherits: 2.0.4 + md5.js: 1.3.5 + ripemd160: 2.0.3 + sha.js: 2.4.12 + + create-hmac@1.1.7: + dependencies: + cipher-base: 1.0.7 + create-hash: 1.2.0 + inherits: 2.0.4 + ripemd160: 2.0.3 + safe-buffer: 5.2.1 + sha.js: 2.4.12 + + cross-spawn@5.1.0: + dependencies: + lru-cache: 4.1.5 + shebang-command: 1.2.0 + which: 1.3.1 + + cross-spawn@6.0.6: + dependencies: + nice-try: 1.0.5 + path-key: 2.0.1 + semver: 5.7.2 + shebang-command: 1.2.0 + which: 1.3.1 + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + crypto-browserify@3.12.1: + dependencies: + browserify-cipher: 1.0.1 + browserify-sign: 4.2.5 + create-ecdh: 4.0.4 + create-hash: 1.2.0 + create-hmac: 1.1.7 + diffie-hellman: 5.0.3 + hash-base: 3.0.5 + inherits: 2.0.4 + pbkdf2: 3.1.5 + public-encrypt: 4.0.3 + randombytes: 2.1.0 + randomfill: 1.0.4 + + css-color-names@0.0.4: {} + + css-declaration-sorter@4.0.1: + dependencies: + postcss: 7.0.39 + timsort: 0.3.0 + + css-loader@3.6.0(webpack@4.47.0): + dependencies: + camelcase: 5.3.1 + cssesc: 3.0.0 + icss-utils: 4.1.1 + loader-utils: 1.4.2 + normalize-path: 3.0.0 + postcss: 7.0.39 + postcss-modules-extract-imports: 2.0.0 + postcss-modules-local-by-default: 3.0.3 + postcss-modules-scope: 2.2.0 + postcss-modules-values: 3.0.0 + postcss-value-parser: 4.2.0 + schema-utils: 2.7.1 + semver: 6.3.1 + webpack: 4.47.0 + + css-select-base-adapter@0.1.1: {} + + css-select@2.1.0: + dependencies: + boolbase: 1.0.0 + css-what: 3.4.2 + domutils: 1.7.0 + nth-check: 1.0.2 + + css-select@4.3.0: + dependencies: + boolbase: 1.0.0 + css-what: 6.2.2 + domhandler: 4.3.1 + domutils: 2.8.0 + nth-check: 2.1.1 + + css-tree@1.0.0-alpha.37: + dependencies: + mdn-data: 2.0.4 + source-map: 0.6.1 + + css-tree@1.1.3: + dependencies: + mdn-data: 2.0.14 + source-map: 0.6.1 + + css-what@3.4.2: {} + + css-what@6.2.2: {} + + cssesc@3.0.0: {} + + cssnano-preset-default@4.0.8: + dependencies: + css-declaration-sorter: 4.0.1 + cssnano-util-raw-cache: 4.0.1 + postcss: 7.0.39 + postcss-calc: 7.0.5 + postcss-colormin: 4.0.3 + postcss-convert-values: 4.0.1 + postcss-discard-comments: 4.0.2 + postcss-discard-duplicates: 4.0.2 + postcss-discard-empty: 4.0.1 + postcss-discard-overridden: 4.0.1 + postcss-merge-longhand: 4.0.11 + postcss-merge-rules: 4.0.3 + postcss-minify-font-values: 4.0.2 + postcss-minify-gradients: 4.0.2 + postcss-minify-params: 4.0.2 + postcss-minify-selectors: 4.0.2 + postcss-normalize-charset: 4.0.1 + postcss-normalize-display-values: 4.0.2 + postcss-normalize-positions: 4.0.2 + postcss-normalize-repeat-style: 4.0.2 + postcss-normalize-string: 4.0.2 + postcss-normalize-timing-functions: 4.0.2 + postcss-normalize-unicode: 4.0.1 + postcss-normalize-url: 4.0.1 + postcss-normalize-whitespace: 4.0.2 + postcss-ordered-values: 4.1.2 + postcss-reduce-initial: 4.0.3 + postcss-reduce-transforms: 4.0.2 + postcss-svgo: 4.0.3 + postcss-unique-selectors: 4.0.1 + + cssnano-util-get-arguments@4.0.0: {} + + cssnano-util-get-match@4.0.0: {} + + cssnano-util-raw-cache@4.0.1: + dependencies: + postcss: 7.0.39 + + cssnano-util-same-parent@4.0.1: {} + + cssnano@4.1.11: + dependencies: + cosmiconfig: 5.2.1 + cssnano-preset-default: 4.0.8 + is-resolvable: 1.1.0 + postcss: 7.0.39 + + csso@4.2.0: + dependencies: + css-tree: 1.1.3 + + cyclist@1.0.2: {} + + dashdash@1.14.1: + dependencies: + assert-plus: 1.0.0 + + data-view-buffer@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-offset@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + de-indent@1.0.2: {} + + debug@2.6.9(supports-color@6.1.0): + dependencies: + ms: 2.0.0 + optionalDependencies: + supports-color: 6.1.0 + + debug@3.2.7(supports-color@6.1.0): + dependencies: + ms: 2.1.3 + optionalDependencies: + supports-color: 6.1.0 + + debug@4.4.3(supports-color@6.1.0): + dependencies: + ms: 2.1.3 + optionalDependencies: + supports-color: 6.1.0 + + decamelize@1.2.0: {} + + decode-uri-component@0.2.2: {} + + dedent@0.7.0: {} + + deep-equal@1.1.2: + dependencies: + is-arguments: 1.2.0 + is-date-object: 1.1.0 + is-regex: 1.2.1 + object-is: 1.1.6 + object-keys: 1.1.1 + regexp.prototype.flags: 1.5.4 + + deep-is@0.1.4: {} + + deepmerge@1.3.2: {} + + deepmerge@1.5.2: {} + + deepmerge@4.3.1: {} + + default-gateway@4.2.0: + dependencies: + execa: 1.0.0 + ip-regex: 2.1.0 + + default-gateway@5.0.5: + dependencies: + execa: 3.4.0 + + defaults@1.0.4: + dependencies: + clone: 1.0.4 + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + + define-property@0.2.5: + dependencies: + is-descriptor: 0.1.7 + + define-property@1.0.0: + dependencies: + is-descriptor: 1.0.3 + + define-property@2.0.2: + dependencies: + is-descriptor: 1.0.3 + isobject: 3.0.1 + + del@4.1.1: + dependencies: + '@types/glob': 7.2.0 + globby: 6.1.0 + is-path-cwd: 2.2.0 + is-path-in-cwd: 2.1.0 + p-map: 2.1.0 + pify: 4.0.1 + rimraf: 2.7.1 + + delayed-stream@1.0.0: {} + + delegate@3.2.0: {} + + depd@1.1.2: {} + + depd@2.0.0: {} + + des.js@1.1.0: + dependencies: + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + + destroy@1.2.0: {} + + detect-node@2.1.0: {} + + diffie-hellman@5.0.3: + dependencies: + bn.js: 4.12.3 + miller-rabin: 4.0.1 + randombytes: 2.1.0 + + dir-glob@2.2.2: + dependencies: + path-type: 3.0.0 + + dns-equal@1.0.0: {} + + dns-packet@5.6.1: + dependencies: + '@leichtgewicht/ip-codec': 2.0.5 + + dns-txt@2.0.2: + dependencies: + buffer-indexof: 1.1.1 + + doctrine@3.0.0: + dependencies: + esutils: 2.0.3 + + dom-converter@0.2.0: + dependencies: + utila: 0.4.0 + + dom-serializer@0.2.2: + dependencies: + domelementtype: 2.3.0 + entities: 2.2.0 + + dom-serializer@1.4.1: + dependencies: + domelementtype: 2.3.0 + domhandler: 4.3.1 + entities: 2.2.0 + + domain-browser@1.2.0: {} + + domelementtype@1.3.1: {} + + domelementtype@2.3.0: {} + + domhandler@2.4.2: + dependencies: + domelementtype: 1.3.1 + + domhandler@4.3.1: + dependencies: + domelementtype: 2.3.0 + + domready@1.0.8: {} + + domutils@1.7.0: + dependencies: + dom-serializer: 0.2.2 + domelementtype: 1.3.1 + + domutils@2.8.0: + dependencies: + dom-serializer: 1.4.1 + domelementtype: 2.3.0 + domhandler: 4.3.1 + + dot-prop@5.3.0: + dependencies: + is-obj: 2.0.0 + + dotenv-expand@5.1.0: {} + + dotenv@8.6.0: {} + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + duplexer@0.1.2: {} + + duplexify@3.7.1: + dependencies: + end-of-stream: 1.4.5 + inherits: 2.0.4 + readable-stream: 2.3.8 + stream-shift: 1.0.3 + + easings-css@1.0.0: {} + + easy-stack@1.0.1: {} + + ecc-jsbn@0.1.2: + dependencies: + jsbn: 0.1.1 + safer-buffer: 2.1.2 + + echarts@5.4.0: + dependencies: + tslib: 2.3.0 + zrender: 5.4.0 + + editorconfig@0.15.3: + dependencies: + commander: 2.20.3 + lru-cache: 4.1.5 + semver: 5.7.2 + sigmund: 1.0.1 + + ee-first@1.1.1: {} + + ejs@2.7.4: {} + + electron-to-chromium@1.5.344: {} + + element-ui@2.15.14(vue@2.6.12): + dependencies: + async-validator: 1.8.5 + babel-helper-vue-jsx-merge-props: 2.0.3 + deepmerge: 1.5.2 + normalize-wheel: 1.0.1 + resize-observer-polyfill: 1.5.1 + throttle-debounce: 1.1.0 + vue: 2.6.12 + + elliptic@6.6.1: + dependencies: + bn.js: 4.12.3 + brorand: 1.1.0 + hash.js: 1.1.7 + hmac-drbg: 1.0.1 + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + minimalistic-crypto-utils: 1.0.1 + + emoji-regex@7.0.3: {} + + emoji-regex@8.0.0: {} + + emojis-list@2.1.0: {} + + emojis-list@3.0.0: {} + + encodeurl@1.0.2: {} + + encodeurl@2.0.0: {} + + end-of-stream@1.4.5: + dependencies: + once: 1.4.0 + + enhanced-resolve@4.5.0: + dependencies: + graceful-fs: 4.2.11 + memory-fs: 0.5.0 + tapable: 1.1.3 + + enquirer@2.4.1: + dependencies: + ansi-colors: 4.1.3 + strip-ansi: 6.0.1 + + entities@1.1.2: {} + + entities@2.2.0: {} + + entities@7.0.1: {} + + errno@0.1.8: + dependencies: + prr: 1.0.1 + + error-ex@1.3.4: + dependencies: + is-arrayish: 0.2.1 + + error-stack-parser@2.1.4: + dependencies: + stackframe: 1.3.4 + + es-abstract@1.24.2: + dependencies: + array-buffer-byte-length: 1.0.2 + arraybuffer.prototype.slice: 1.0.4 + available-typed-arrays: 1.0.7 + call-bind: 1.0.9 + call-bound: 1.0.4 + data-view-buffer: 1.0.2 + data-view-byte-length: 1.0.2 + data-view-byte-offset: 1.0.1 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-set-tostringtag: 2.1.0 + es-to-primitive: 1.3.0 + function.prototype.name: 1.1.8 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + get-symbol-description: 1.1.0 + globalthis: 1.0.4 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + has-proto: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.3 + internal-slot: 1.1.0 + is-array-buffer: 3.0.5 + is-callable: 1.2.7 + is-data-view: 1.0.2 + is-negative-zero: 2.0.3 + is-regex: 1.2.1 + is-set: 2.0.3 + is-shared-array-buffer: 1.0.4 + is-string: 1.1.1 + is-typed-array: 1.1.15 + is-weakref: 1.1.1 + math-intrinsics: 1.1.0 + object-inspect: 1.13.4 + object-keys: 1.1.1 + object.assign: 4.1.7 + own-keys: 1.0.1 + regexp.prototype.flags: 1.5.4 + safe-array-concat: 1.1.4 + safe-push-apply: 1.0.0 + safe-regex-test: 1.1.0 + set-proto: 1.0.0 + stop-iteration-iterator: 1.1.0 + string.prototype.trim: 1.2.10 + string.prototype.trimend: 1.0.9 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.3 + typed-array-byte-length: 1.0.3 + typed-array-byte-offset: 1.0.4 + typed-array-length: 1.0.7 + unbox-primitive: 1.1.0 + which-typed-array: 1.1.20 + + es-array-method-boxes-properly@1.0.0: {} + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.3 + + es-to-primitive@1.3.0: + dependencies: + is-callable: 1.2.7 + is-date-object: 1.1.0 + is-symbol: 1.1.1 + + escalade@3.2.0: {} + + escape-html@1.0.3: {} + + escape-string-regexp@1.0.5: {} + + eslint-loader@2.2.1(eslint@7.15.0)(webpack@4.47.0): + dependencies: + eslint: 7.15.0 + loader-fs-cache: 1.0.3 + loader-utils: 1.4.2 + object-assign: 4.1.1 + object-hash: 1.3.1 + rimraf: 2.7.1 + webpack: 4.47.0 + + eslint-plugin-vue@7.2.0(eslint@7.15.0): + dependencies: + eslint: 7.15.0 + eslint-utils: 2.1.0 + natural-compare: 1.4.0 + semver: 7.7.4 + vue-eslint-parser: 7.11.0(eslint@7.15.0) + transitivePeerDependencies: + - supports-color + + eslint-scope@4.0.3: + dependencies: + esrecurse: 4.3.0 + estraverse: 4.3.0 + + eslint-scope@5.1.1: + dependencies: + esrecurse: 4.3.0 + estraverse: 4.3.0 + + eslint-utils@2.1.0: + dependencies: + eslint-visitor-keys: 1.3.0 + + eslint-visitor-keys@1.3.0: {} + + eslint-visitor-keys@2.1.0: {} + + eslint@7.15.0: + dependencies: + '@babel/code-frame': 7.29.0 + '@eslint/eslintrc': 0.2.2 + ajv: 6.15.0 + chalk: 4.1.0 + cross-spawn: 7.0.6 + debug: 4.4.3(supports-color@6.1.0) + doctrine: 3.0.0 + enquirer: 2.4.1 + eslint-scope: 5.1.1 + eslint-utils: 2.1.0 + eslint-visitor-keys: 2.1.0 + espree: 7.3.1 + esquery: 1.7.0 + esutils: 2.0.3 + file-entry-cache: 6.0.1 + functional-red-black-tree: 1.0.1 + glob-parent: 5.1.2 + globals: 12.4.0 + ignore: 4.0.6 + import-fresh: 3.3.1 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + js-yaml: 3.14.2 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash: 4.18.1 + minimatch: 3.1.5 + natural-compare: 1.4.0 + optionator: 0.9.4 + progress: 2.0.3 + regexpp: 3.2.0 + semver: 7.7.4 + strip-ansi: 6.0.1 + strip-json-comments: 3.1.1 + table: 5.4.6 + text-table: 0.2.0 + v8-compile-cache: 2.4.0 + transitivePeerDependencies: + - supports-color + + espree@6.2.1: + dependencies: + acorn: 7.4.1 + acorn-jsx: 5.3.2(acorn@7.4.1) + eslint-visitor-keys: 1.3.0 + + espree@7.3.1: + dependencies: + acorn: 7.4.1 + acorn-jsx: 5.3.2(acorn@7.4.1) + eslint-visitor-keys: 1.3.0 + + esprima@4.0.1: {} + + esquery@1.7.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@4.3.0: {} + + estraverse@5.3.0: {} + + estree-walker@2.0.2: {} + + esutils@2.0.3: {} + + etag@1.8.1: {} + + event-pubsub@4.3.0: {} + + eventemitter3@2.0.3: {} + + eventemitter3@4.0.7: {} + + events@3.3.0: {} + + eventsource@2.0.2: {} + + evp_bytestokey@1.0.3: + dependencies: + md5.js: 1.3.5 + safe-buffer: 5.2.1 + + execa@0.8.0: + dependencies: + cross-spawn: 5.1.0 + get-stream: 3.0.0 + is-stream: 1.1.0 + npm-run-path: 2.0.2 + p-finally: 1.0.0 + signal-exit: 3.0.7 + strip-eof: 1.0.0 + + execa@1.0.0: + dependencies: + cross-spawn: 6.0.6 + get-stream: 4.1.0 + is-stream: 1.1.0 + npm-run-path: 2.0.2 + p-finally: 1.0.0 + signal-exit: 3.0.7 + strip-eof: 1.0.0 + + execa@3.4.0: + dependencies: + cross-spawn: 7.0.6 + get-stream: 5.2.0 + human-signals: 1.1.1 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + p-finally: 2.0.1 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + + execa@4.1.0: + dependencies: + cross-spawn: 7.0.6 + get-stream: 5.2.0 + human-signals: 1.1.1 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + + expand-brackets@2.1.4(supports-color@6.1.0): + dependencies: + debug: 2.6.9(supports-color@6.1.0) + define-property: 0.2.5 + extend-shallow: 2.0.1 + posix-character-classes: 0.1.1 + regex-not: 1.0.2 + snapdragon: 0.8.2(supports-color@6.1.0) + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + + express@4.22.1(supports-color@6.1.0): + dependencies: + accepts: 1.3.8 + array-flatten: 1.1.1 + body-parser: 1.20.5(supports-color@6.1.0) + content-disposition: 0.5.4 + content-type: 1.0.5 + cookie: 0.7.2 + cookie-signature: 1.0.7 + debug: 2.6.9(supports-color@6.1.0) + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 1.3.2(supports-color@6.1.0) + fresh: 0.5.2 + http-errors: 2.0.1 + merge-descriptors: 1.0.3 + methods: 1.1.2 + on-finished: 2.4.1 + parseurl: 1.3.3 + path-to-regexp: 0.1.13 + proxy-addr: 2.0.7 + qs: 6.14.2 + range-parser: 1.2.1 + safe-buffer: 5.2.1 + send: 0.19.2(supports-color@6.1.0) + serve-static: 1.16.3(supports-color@6.1.0) + setprototypeof: 1.2.0 + statuses: 2.0.2 + type-is: 1.6.18 + utils-merge: 1.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + extend-shallow@2.0.1: + dependencies: + is-extendable: 0.1.1 + + extend-shallow@3.0.2: + dependencies: + assign-symbols: 1.0.0 + is-extendable: 1.0.1 + + extend@3.0.2: {} + + external-editor@3.1.0: + dependencies: + chardet: 0.7.0 + iconv-lite: 0.4.24 + tmp: 0.0.33 + + extglob@2.0.4(supports-color@6.1.0): + dependencies: + array-unique: 0.3.2 + define-property: 1.0.0 + expand-brackets: 2.1.4(supports-color@6.1.0) + extend-shallow: 2.0.1 + fragment-cache: 0.2.1 + regex-not: 1.0.2 + snapdragon: 0.8.2(supports-color@6.1.0) + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + + extsprintf@1.3.0: {} + + fast-deep-equal@3.1.3: {} + + fast-diff@1.1.2: {} + + fast-glob@2.2.7: + dependencies: + '@mrmlnc/readdir-enhanced': 2.2.1 + '@nodelib/fs.stat': 1.1.3 + glob-parent: 3.1.0 + is-glob: 4.0.3 + merge2: 1.4.1 + micromatch: 3.1.10(supports-color@6.1.0) + transitivePeerDependencies: + - supports-color + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + faye-websocket@0.11.4: + dependencies: + websocket-driver: 0.7.4 + + figgy-pudding@3.5.2: {} + + figures@3.2.0: + dependencies: + escape-string-regexp: 1.0.5 + + file-entry-cache@6.0.1: + dependencies: + flat-cache: 3.2.0 + + file-loader@4.3.0(webpack@4.47.0): + dependencies: + loader-utils: 1.4.2 + schema-utils: 2.7.1 + webpack: 4.47.0 + + file-saver@2.0.5: {} + + file-uri-to-path@1.0.0: + optional: true + + filesize@3.6.1: {} + + fill-range@4.0.0: + dependencies: + extend-shallow: 2.0.1 + is-number: 3.0.0 + repeat-string: 1.6.1 + to-regex-range: 2.1.1 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + finalhandler@1.1.0: + dependencies: + debug: 2.6.9(supports-color@6.1.0) + encodeurl: 1.0.2 + escape-html: 1.0.3 + on-finished: 2.3.0 + parseurl: 1.3.3 + statuses: 1.3.1 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + finalhandler@1.3.2(supports-color@6.1.0): + dependencies: + debug: 2.6.9(supports-color@6.1.0) + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.2 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + find-cache-dir@0.1.1: + dependencies: + commondir: 1.0.1 + mkdirp: 0.5.6 + pkg-dir: 1.0.0 + + find-cache-dir@2.1.0: + dependencies: + commondir: 1.0.1 + make-dir: 2.1.0 + pkg-dir: 3.0.0 + + find-cache-dir@3.3.2: + dependencies: + commondir: 1.0.1 + make-dir: 3.1.0 + pkg-dir: 4.2.0 + + find-up@1.1.2: + dependencies: + path-exists: 2.1.0 + pinkie-promise: 2.0.1 + + find-up@3.0.0: + dependencies: + locate-path: 3.0.0 + + find-up@4.1.0: + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + + flat-cache@3.2.0: + dependencies: + flatted: 3.4.2 + keyv: 4.5.4 + rimraf: 3.0.2 + + flatted@3.4.2: {} + + flush-write-stream@1.1.1: + dependencies: + inherits: 2.0.4 + readable-stream: 2.3.8 + + follow-redirects@1.16.0(debug@4.4.3): + optionalDependencies: + debug: 4.4.3(supports-color@6.1.0) + + for-each@0.3.5: + dependencies: + is-callable: 1.2.7 + + for-in@1.0.2: {} + + forever-agent@0.6.1: {} + + form-data@2.3.3: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + + form-data@4.0.5: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.3 + mime-types: 2.1.35 + + forwarded@0.2.0: {} + + fragment-cache@0.2.1: + dependencies: + map-cache: 0.2.2 + + fresh@0.5.2: {} + + from2@2.3.0: + dependencies: + inherits: 2.0.4 + readable-stream: 2.3.8 + + fs-extra@7.0.1: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + + fs-minipass@2.1.0: + dependencies: + minipass: 3.3.6 + + fs-write-stream-atomic@1.0.10: + dependencies: + graceful-fs: 4.2.11 + iferr: 0.1.5 + imurmurhash: 0.1.4 + readable-stream: 2.3.8 + + fs.realpath@1.0.0: {} + + fsevents@1.2.13: + dependencies: + bindings: 1.5.0 + nan: 2.26.2 + optional: true + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + function.prototype.name@1.1.8: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + functions-have-names: 1.2.3 + hasown: 2.0.3 + is-callable: 1.2.7 + + functional-red-black-tree@1.0.1: {} + + functions-have-names@1.2.3: {} + + fuse.js@6.4.3: {} + + fuzzysearch@1.0.3: {} + + generator-function@2.0.1: {} + + gensync@1.0.0-beta.2: {} + + get-caller-file@2.0.5: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.3 + math-intrinsics: 1.1.0 + + get-own-enumerable-property-symbols@3.0.2: {} + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + get-stream@3.0.0: {} + + get-stream@4.1.0: + dependencies: + pump: 3.0.4 + + get-stream@5.2.0: + dependencies: + pump: 3.0.4 + + get-symbol-description@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + + get-value@2.0.6: {} + + getpass@0.1.7: + dependencies: + assert-plus: 1.0.0 + + glob-parent@3.1.0: + dependencies: + is-glob: 3.1.0 + path-dirname: 1.0.2 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-to-regexp@0.3.0: {} + + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.5 + once: 1.4.0 + path-is-absolute: 1.0.1 + + globals@12.4.0: + dependencies: + type-fest: 0.8.1 + + globalthis@1.0.4: + dependencies: + define-properties: 1.2.1 + gopd: 1.2.0 + + globby@6.1.0: + dependencies: + array-union: 1.0.2 + glob: 7.2.3 + object-assign: 4.1.1 + pify: 2.3.0 + pinkie-promise: 2.0.1 + + globby@7.1.1: + dependencies: + array-union: 1.0.2 + dir-glob: 2.2.2 + glob: 7.2.3 + ignore: 3.3.10 + pify: 3.0.0 + slash: 1.0.0 + + globby@9.2.0: + dependencies: + '@types/glob': 7.2.0 + array-union: 1.0.2 + dir-glob: 2.2.2 + fast-glob: 2.2.7 + glob: 7.2.3 + ignore: 4.0.6 + pify: 4.0.1 + slash: 2.0.0 + transitivePeerDependencies: + - supports-color + + good-listener@1.2.2: + dependencies: + delegate: 3.2.0 + + gopd@1.2.0: {} + + graceful-fs@4.2.11: {} + + gzip-size@5.1.1: + dependencies: + duplexer: 0.1.2 + pify: 4.0.1 + + handle-thing@2.0.1: {} + + har-schema@2.0.0: {} + + har-validator@5.1.5: + dependencies: + ajv: 6.15.0 + har-schema: 2.0.0 + + has-ansi@2.0.0: + dependencies: + ansi-regex: 2.1.1 + + has-bigints@1.1.0: {} + + has-flag@1.0.0: {} + + has-flag@2.0.0: {} + + has-flag@3.0.0: {} + + has-flag@4.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 + + has-proto@1.2.0: + dependencies: + dunder-proto: 1.0.1 + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + has-value@0.3.1: + dependencies: + get-value: 2.0.6 + has-values: 0.1.4 + isobject: 2.1.0 + + has-value@1.0.0: + dependencies: + get-value: 2.0.6 + has-values: 1.0.0 + isobject: 3.0.1 + + has-values@0.1.4: {} + + has-values@1.0.0: + dependencies: + is-number: 3.0.0 + kind-of: 4.0.0 + + has@1.0.4: {} + + hash-base@3.0.5: + dependencies: + inherits: 2.0.4 + safe-buffer: 5.2.1 + + hash-base@3.1.2: + dependencies: + inherits: 2.0.4 + readable-stream: 2.3.8 + safe-buffer: 5.2.1 + to-buffer: 1.2.2 + + hash-sum@1.0.2: {} + + hash-sum@2.0.0: {} + + hash.js@1.1.7: + dependencies: + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + + hasown@2.0.3: + dependencies: + function-bind: 1.1.2 + + he@1.2.0: {} + + hex-color-regex@1.1.0: {} + + highlight.js@10.7.3: {} + + highlight.js@9.18.5: {} + + hmac-drbg@1.0.1: + dependencies: + hash.js: 1.1.7 + minimalistic-assert: 1.0.1 + minimalistic-crypto-utils: 1.0.1 + + hoopy@0.1.4: {} + + hosted-git-info@2.8.9: {} + + hpack.js@2.1.6: + dependencies: + inherits: 2.0.4 + obuf: 1.1.2 + readable-stream: 2.3.8 + wbuf: 1.7.3 + + hsl-regex@1.0.0: {} + + hsla-regex@1.0.0: {} + + html-entities@1.4.0: {} + + html-minifier@3.5.21: + dependencies: + camel-case: 3.0.0 + clean-css: 4.2.4 + commander: 2.17.1 + he: 1.2.0 + param-case: 2.1.1 + relateurl: 0.2.7 + uglify-js: 3.4.10 + + html-tags@2.0.0: {} + + html-webpack-plugin@3.2.0(webpack@4.47.0): + dependencies: + html-minifier: 3.5.21 + loader-utils: 0.2.17 + lodash: 4.18.1 + pretty-error: 2.1.2 + tapable: 1.1.3 + toposort: 1.0.7 + util.promisify: 1.0.0 + webpack: 4.47.0 + + htmlparser2@3.10.1: + dependencies: + domelementtype: 1.3.1 + domhandler: 2.4.2 + domutils: 1.7.0 + entities: 1.1.2 + inherits: 2.0.4 + readable-stream: 3.6.2 + + htmlparser2@6.1.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 4.3.1 + domutils: 2.8.0 + entities: 2.2.0 + + http-deceiver@1.2.7: {} + + http-errors@1.8.1: + dependencies: + depd: 1.1.2 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 1.5.0 + toidentifier: 1.0.1 + + http-errors@2.0.1: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.2 + toidentifier: 1.0.1 + + http-parser-js@0.5.10: {} + + http-proxy-middleware@0.19.1(debug@4.4.3)(supports-color@6.1.0): + dependencies: + http-proxy: 1.18.1(debug@4.4.3) + is-glob: 4.0.3 + lodash: 4.18.1 + micromatch: 3.1.10(supports-color@6.1.0) + transitivePeerDependencies: + - debug + - supports-color + + http-proxy@1.18.1(debug@4.4.3): + dependencies: + eventemitter3: 4.0.7 + follow-redirects: 1.16.0(debug@4.4.3) + requires-port: 1.0.0 + transitivePeerDependencies: + - debug + + http-signature@1.2.0: + dependencies: + assert-plus: 1.0.0 + jsprim: 1.4.2 + sshpk: 1.18.0 + + https-browserify@1.0.0: {} + + human-signals@1.1.1: {} + + iconv-lite@0.4.24: + dependencies: + safer-buffer: 2.1.2 + + icss-utils@4.1.1: + dependencies: + postcss: 7.0.39 + + ieee754@1.2.1: {} + + iferr@0.1.5: {} + + ignore@3.3.10: {} + + ignore@4.0.6: {} + + image-size@0.5.5: {} + + import-cwd@2.1.0: + dependencies: + import-from: 2.1.0 + + import-fresh@2.0.0: + dependencies: + caller-path: 2.0.0 + resolve-from: 3.0.0 + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + import-from@2.1.0: + dependencies: + resolve-from: 3.0.0 + + import-local@2.0.0: + dependencies: + pkg-dir: 3.0.0 + resolve-cwd: 2.0.0 + + imurmurhash@0.1.4: {} + + indent-string@4.0.0: {} + + indexes-of@1.0.1: {} + + infer-owner@1.0.4: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.3: {} + + inherits@2.0.4: {} + + ini@1.3.8: {} + + inquirer@7.3.3: + dependencies: + ansi-escapes: 4.3.2 + chalk: 4.1.0 + cli-cursor: 3.1.0 + cli-width: 3.0.0 + external-editor: 3.1.0 + figures: 3.2.0 + lodash: 4.18.1 + mute-stream: 0.0.8 + run-async: 2.4.1 + rxjs: 6.6.7 + string-width: 4.2.3 + strip-ansi: 6.0.1 + through: 2.3.8 + + internal-ip@4.3.0: + dependencies: + default-gateway: 4.2.0 + ipaddr.js: 1.9.1 + + internal-slot@1.1.0: + dependencies: + es-errors: 1.3.0 + hasown: 2.0.3 + side-channel: 1.1.0 + + ip-regex@2.1.0: {} + + ip@1.1.9: {} + + ipaddr.js@1.9.1: {} + + is-absolute-url@2.1.0: {} + + is-absolute-url@3.0.3: {} + + is-accessor-descriptor@1.0.1: + dependencies: + hasown: 2.0.3 + + is-arguments@1.2.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-array-buffer@3.0.5: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + + is-arrayish@0.2.1: {} + + is-arrayish@0.3.4: {} + + is-async-function@2.1.1: + dependencies: + async-function: 1.0.0 + call-bound: 1.0.4 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-bigint@1.1.0: + dependencies: + has-bigints: 1.1.0 + + is-binary-path@1.0.1: + dependencies: + binary-extensions: 1.13.1 + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-boolean-object@1.2.2: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-buffer@1.1.6: {} + + is-callable@1.2.7: {} + + is-ci@1.2.1: + dependencies: + ci-info: 1.6.0 + + is-color-stop@1.1.0: + dependencies: + css-color-names: 0.0.4 + hex-color-regex: 1.1.0 + hsl-regex: 1.0.0 + hsla-regex: 1.0.0 + rgb-regex: 1.0.1 + rgba-regex: 1.0.0 + + is-core-module@2.16.1: + dependencies: + hasown: 2.0.3 + + is-data-descriptor@1.0.1: + dependencies: + hasown: 2.0.3 + + is-data-view@1.0.2: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + is-typed-array: 1.1.15 + + is-date-object@1.1.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-descriptor@0.1.7: + dependencies: + is-accessor-descriptor: 1.0.1 + is-data-descriptor: 1.0.1 + + is-descriptor@1.0.3: + dependencies: + is-accessor-descriptor: 1.0.1 + is-data-descriptor: 1.0.1 + + is-directory@0.3.1: {} + + is-docker@2.2.1: {} + + is-extendable@0.1.1: {} + + is-extendable@1.0.1: + dependencies: + is-plain-object: 2.0.4 + + is-extglob@2.1.1: {} + + is-finalizationregistry@1.1.1: + dependencies: + call-bound: 1.0.4 + + is-fullwidth-code-point@2.0.0: {} + + is-fullwidth-code-point@3.0.0: {} + + is-generator-function@1.1.2: + dependencies: + call-bound: 1.0.4 + generator-function: 2.0.1 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-glob@3.1.0: + dependencies: + is-extglob: 2.1.1 + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-map@2.0.3: {} + + is-negative-zero@2.0.3: {} + + is-number-object@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-number@3.0.0: + dependencies: + kind-of: 3.2.2 + + is-number@7.0.0: {} + + is-obj@1.0.1: {} + + is-obj@2.0.0: {} + + is-path-cwd@2.2.0: {} + + is-path-in-cwd@2.1.0: + dependencies: + is-path-inside: 2.1.0 + + is-path-inside@2.1.0: + dependencies: + path-is-inside: 1.0.2 + + is-plain-obj@1.1.0: {} + + is-plain-object@2.0.4: + dependencies: + isobject: 3.0.1 + + is-promise@2.2.2: {} + + is-regex@1.2.1: + dependencies: + call-bound: 1.0.4 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + hasown: 2.0.3 + + is-regexp@1.0.0: {} + + is-resolvable@1.1.0: {} + + is-set@2.0.3: {} + + is-shared-array-buffer@1.0.4: + dependencies: + call-bound: 1.0.4 + + is-stream@1.1.0: {} + + is-stream@2.0.1: {} + + is-string@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-symbol@1.1.1: + dependencies: + call-bound: 1.0.4 + has-symbols: 1.1.0 + safe-regex-test: 1.1.0 + + is-typed-array@1.1.15: + dependencies: + which-typed-array: 1.1.20 + + is-typedarray@1.0.0: {} + + is-unicode-supported@0.1.0: {} + + is-weakmap@2.0.2: {} + + is-weakref@1.1.1: + dependencies: + call-bound: 1.0.4 + + is-weakset@2.0.4: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + + is-windows@1.0.2: {} + + is-wsl@1.1.0: {} + + is-wsl@2.2.0: + dependencies: + is-docker: 2.2.1 + + isarray@1.0.0: {} + + isarray@2.0.5: {} + + isexe@2.0.0: {} + + isobject@2.1.0: + dependencies: + isarray: 1.0.0 + + isobject@3.0.1: {} + + isstream@0.1.2: {} + + javascript-stringify@2.1.0: {} + + jest-worker@25.5.0: + dependencies: + merge-stream: 2.0.0 + supports-color: 7.2.0 + + js-base64@2.6.4: {} + + js-beautify@1.13.0: + dependencies: + config-chain: 1.1.13 + editorconfig: 0.15.3 + glob: 7.2.3 + mkdirp: 1.0.4 + nopt: 5.0.0 + + js-cookie@3.0.1: {} + + js-message@1.0.7: {} + + js-tokens@4.0.0: {} + + js-yaml@3.14.2: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + jsbn@0.1.1: {} + + jsencrypt@3.0.0-rc.1: {} + + jsesc@3.1.0: {} + + json-buffer@3.0.1: {} + + json-parse-better-errors@1.0.2: {} + + json-parse-even-better-errors@2.3.1: {} + + json-schema-traverse@0.4.1: {} + + json-schema@0.4.0: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json-stringify-safe@5.0.1: {} + + json5@0.5.1: {} + + json5@1.0.2: + dependencies: + minimist: 1.2.8 + + json5@2.2.3: {} + + jsonfile@4.0.0: + optionalDependencies: + graceful-fs: 4.2.11 + + jsprim@1.4.2: + dependencies: + assert-plus: 1.0.0 + extsprintf: 1.3.0 + json-schema: 0.4.0 + verror: 1.10.0 + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + killable@1.0.1: {} + + kind-of@3.2.2: + dependencies: + is-buffer: 1.1.6 + + kind-of@4.0.0: + dependencies: + is-buffer: 1.1.6 + + kind-of@5.1.0: {} + + kind-of@6.0.3: {} + + klona@2.0.6: {} + + launch-editor-middleware@2.13.2: + dependencies: + launch-editor: 2.13.2 + + launch-editor@2.13.2: + dependencies: + picocolors: 1.1.1 + shell-quote: 1.8.3 + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + lines-and-columns@1.2.4: {} + + lint-staged@10.5.3: + dependencies: + chalk: 4.1.0 + cli-truncate: 2.1.0 + commander: 6.2.1 + cosmiconfig: 7.1.0 + debug: 4.4.3(supports-color@6.1.0) + dedent: 0.7.0 + enquirer: 2.4.1 + execa: 4.1.0 + listr2: 3.14.0(enquirer@2.4.1) + log-symbols: 4.1.0 + micromatch: 4.0.8 + normalize-path: 3.0.0 + please-upgrade-node: 3.2.0 + string-argv: 0.3.1 + stringify-object: 3.3.0 + transitivePeerDependencies: + - supports-color + + listr2@3.14.0(enquirer@2.4.1): + dependencies: + cli-truncate: 2.1.0 + colorette: 2.0.20 + log-update: 4.0.0 + p-map: 4.0.0 + rfdc: 1.4.1 + rxjs: 7.8.2 + through: 2.3.8 + wrap-ansi: 7.0.0 + optionalDependencies: + enquirer: 2.4.1 + + loader-fs-cache@1.0.3: + dependencies: + find-cache-dir: 0.1.1 + mkdirp: 0.5.6 + + loader-runner@2.4.0: {} + + loader-utils@0.2.17: + dependencies: + big.js: 3.2.0 + emojis-list: 2.1.0 + json5: 0.5.1 + object-assign: 4.1.1 + + loader-utils@1.4.2: + dependencies: + big.js: 5.2.2 + emojis-list: 3.0.0 + json5: 1.0.2 + + loader-utils@2.0.4: + dependencies: + big.js: 5.2.2 + emojis-list: 3.0.0 + json5: 2.2.3 + + locate-path@3.0.0: + dependencies: + p-locate: 3.0.0 + path-exists: 3.0.0 + + locate-path@5.0.0: + dependencies: + p-locate: 4.1.0 + + lodash.debounce@4.0.8: {} + + lodash.defaultsdeep@4.6.1: {} + + lodash.kebabcase@4.1.1: {} + + lodash.mapvalues@4.6.0: {} + + lodash.memoize@4.1.2: {} + + lodash.padend@4.6.1: {} + + lodash.transform@4.6.0: {} + + lodash.uniq@4.5.0: {} + + lodash@4.17.11: {} + + lodash@4.18.1: {} + + log-symbols@2.2.0: + dependencies: + chalk: 2.4.2 + + log-symbols@4.1.0: + dependencies: + chalk: 4.1.0 + is-unicode-supported: 0.1.0 + + log-update@4.0.0: + dependencies: + ansi-escapes: 4.3.2 + cli-cursor: 3.1.0 + slice-ansi: 4.0.0 + wrap-ansi: 6.2.0 + + loglevel@1.9.2: {} + + lower-case@1.1.4: {} + + lru-cache@4.1.5: + dependencies: + pseudomap: 1.0.2 + yallist: 2.1.2 + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + lru-cache@6.0.0: + dependencies: + yallist: 4.0.0 + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + make-dir@2.1.0: + dependencies: + pify: 4.0.1 + semver: 5.7.2 + + make-dir@3.1.0: + dependencies: + semver: 6.3.1 + + map-cache@0.2.2: {} + + map-visit@1.0.0: + dependencies: + object-visit: 1.0.1 + + material-colors@1.2.6: {} + + math-intrinsics@1.1.0: {} + + md5.js@1.3.5: + dependencies: + hash-base: 3.0.5 + inherits: 2.0.4 + safe-buffer: 5.2.1 + + mdn-data@2.0.14: {} + + mdn-data@2.0.4: {} + + media-typer@0.3.0: {} + + memory-fs@0.4.1: + dependencies: + errno: 0.1.8 + readable-stream: 2.3.8 + + memory-fs@0.5.0: + dependencies: + errno: 0.1.8 + readable-stream: 2.3.8 + + merge-descriptors@1.0.3: {} + + merge-options@1.0.1: + dependencies: + is-plain-obj: 1.1.0 + + merge-source-map@1.1.0: + dependencies: + source-map: 0.6.1 + + merge-stream@2.0.0: {} + + merge2@1.4.1: {} + + methods@1.1.2: {} + + microargs@1.1.2: {} + + microcli@1.3.3: + dependencies: + lodash: 4.17.11 + microargs: 1.1.2 + + micromatch@3.1.0: + dependencies: + arr-diff: 4.0.0 + array-unique: 0.3.2 + braces: 2.3.2(supports-color@6.1.0) + define-property: 1.0.0 + extend-shallow: 2.0.1 + extglob: 2.0.4(supports-color@6.1.0) + fragment-cache: 0.2.1 + kind-of: 5.1.0 + nanomatch: 1.2.13(supports-color@6.1.0) + object.pick: 1.3.0 + regex-not: 1.0.2 + snapdragon: 0.8.2(supports-color@6.1.0) + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + + micromatch@3.1.10(supports-color@6.1.0): + dependencies: + arr-diff: 4.0.0 + array-unique: 0.3.2 + braces: 2.3.2(supports-color@6.1.0) + define-property: 2.0.2 + extend-shallow: 3.0.2 + extglob: 2.0.4(supports-color@6.1.0) + fragment-cache: 0.2.1 + kind-of: 6.0.3 + nanomatch: 1.2.13(supports-color@6.1.0) + object.pick: 1.3.0 + regex-not: 1.0.2 + snapdragon: 0.8.2(supports-color@6.1.0) + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.2 + + miller-rabin@4.0.1: + dependencies: + bn.js: 4.12.3 + brorand: 1.1.0 + + mime-db@1.52.0: {} + + mime-db@1.54.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mime@1.6.0: {} + + mime@2.6.0: {} + + mimic-fn@1.2.0: {} + + mimic-fn@2.1.0: {} + + mini-css-extract-plugin@0.9.0(webpack@4.47.0): + dependencies: + loader-utils: 1.4.2 + normalize-url: 1.9.1 + schema-utils: 1.0.0 + webpack: 4.47.0 + webpack-sources: 1.4.3 + + minimalistic-assert@1.0.1: {} + + minimalistic-crypto-utils@1.0.1: {} + + minimatch@10.2.5: + dependencies: + brace-expansion: 5.0.5 + + minimatch@3.1.5: + dependencies: + brace-expansion: 1.1.14 + + minimist@1.2.8: {} + + minipass-collect@1.0.2: + dependencies: + minipass: 3.3.6 + + minipass-flush@1.0.7: + dependencies: + minipass: 3.3.6 + + minipass-pipeline@1.2.4: + dependencies: + minipass: 3.3.6 + + minipass@3.3.6: + dependencies: + yallist: 4.0.0 + + minipass@5.0.0: {} + + minizlib@2.1.2: + dependencies: + minipass: 3.3.6 + yallist: 4.0.0 + + mississippi@3.0.0: + dependencies: + concat-stream: 1.6.2 + duplexify: 3.7.1 + end-of-stream: 1.4.5 + flush-write-stream: 1.1.1 + from2: 2.3.0 + parallel-transform: 1.2.0 + pump: 3.0.4 + pumpify: 1.5.1 + stream-each: 1.2.3 + through2: 2.0.5 + + mitt@1.1.2: {} + + mixin-deep@1.3.2: + dependencies: + for-in: 1.0.2 + is-extendable: 1.0.1 + + mkdirp@0.5.6: + dependencies: + minimist: 1.2.8 + + mkdirp@1.0.4: {} + + move-concurrently@1.0.1: + dependencies: + aproba: 1.2.0 + copy-concurrently: 1.0.5 + fs-write-stream-atomic: 1.0.10 + mkdirp: 0.5.6 + rimraf: 2.7.1 + run-queue: 1.0.3 + + ms@2.0.0: {} + + ms@2.1.3: {} + + multicast-dns-service-types@1.1.0: {} + + multicast-dns@7.2.5: + dependencies: + dns-packet: 5.6.1 + thunky: 1.1.0 + + mute-stream@0.0.8: {} + + mz@2.7.0: + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + + nan@2.26.2: + optional: true + + nanoid@3.3.11: {} + + nanomatch@1.2.13(supports-color@6.1.0): + dependencies: + arr-diff: 4.0.0 + array-unique: 0.3.2 + define-property: 2.0.2 + extend-shallow: 3.0.2 + fragment-cache: 0.2.1 + is-windows: 1.0.2 + kind-of: 6.0.3 + object.pick: 1.3.0 + regex-not: 1.0.2 + snapdragon: 0.8.2(supports-color@6.1.0) + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + + natural-compare@1.4.0: {} + + negotiator@0.6.3: {} + + negotiator@0.6.4: {} + + neo-async@2.6.2: {} + + nice-try@1.0.5: {} + + no-case@2.3.2: + dependencies: + lower-case: 1.1.4 + + node-forge@0.10.0: {} + + node-libs-browser@2.2.1: + dependencies: + assert: 1.5.1 + browserify-zlib: 0.2.0 + buffer: 4.9.2 + console-browserify: 1.2.0 + constants-browserify: 1.0.0 + crypto-browserify: 3.12.1 + domain-browser: 1.2.0 + events: 3.3.0 + https-browserify: 1.0.0 + os-browserify: 0.3.0 + path-browserify: 0.0.1 + process: 0.11.10 + punycode: 1.4.1 + querystring-es3: 0.2.1 + readable-stream: 2.3.8 + stream-browserify: 2.0.2 + stream-http: 2.8.3 + string_decoder: 1.3.0 + timers-browserify: 2.0.12 + tty-browserify: 0.0.0 + url: 0.11.4 + util: 0.11.1 + vm-browserify: 1.1.2 + + node-releases@2.0.38: {} + + nopt@5.0.0: + dependencies: + abbrev: 1.1.1 + + normalize-package-data@2.5.0: + dependencies: + hosted-git-info: 2.8.9 + resolve: 1.22.12 + semver: 5.7.2 + validate-npm-package-license: 3.0.4 + + normalize-path@1.0.0: {} + + normalize-path@2.1.1: + dependencies: + remove-trailing-separator: 1.1.0 + + normalize-path@3.0.0: {} + + normalize-range@0.1.2: {} + + normalize-url@1.9.1: + dependencies: + object-assign: 4.1.1 + prepend-http: 1.0.4 + query-string: 4.3.4 + sort-keys: 1.1.2 + + normalize-url@3.3.0: {} + + normalize-wheel@1.0.1: {} + + npm-run-path@2.0.2: + dependencies: + path-key: 2.0.1 + + npm-run-path@4.0.1: + dependencies: + path-key: 3.1.1 + + nprogress@0.2.0: {} + + nth-check@1.0.2: + dependencies: + boolbase: 1.0.0 + + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + + num2fraction@1.2.2: {} + + oauth-sign@0.9.0: {} + + object-assign@4.1.1: {} + + object-copy@0.1.0: + dependencies: + copy-descriptor: 0.1.1 + define-property: 0.2.5 + kind-of: 3.2.2 + + object-hash@1.3.1: {} + + object-inspect@1.13.4: {} + + object-is@1.1.6: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + + object-keys@1.1.1: {} + + object-visit@1.0.1: + dependencies: + isobject: 3.0.1 + + object.assign@4.1.7: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + has-symbols: 1.1.0 + object-keys: 1.1.1 + + object.getownpropertydescriptors@2.1.9: + dependencies: + array.prototype.reduce: 1.0.8 + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-object-atoms: 1.1.1 + gopd: 1.2.0 + safe-array-concat: 1.1.4 + + object.pick@1.3.0: + dependencies: + isobject: 3.0.1 + + object.values@1.2.1: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + obuf@1.1.2: {} + + omelette@0.4.5: {} + + on-finished@2.3.0: + dependencies: + ee-first: 1.1.1 + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + + on-headers@1.1.0: {} + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + onetime@2.0.1: + dependencies: + mimic-fn: 1.2.0 + + onetime@5.1.2: + dependencies: + mimic-fn: 2.1.0 + + open@6.4.0: + dependencies: + is-wsl: 1.1.0 + + opener@1.5.2: {} + + opn@5.5.0: + dependencies: + is-wsl: 1.1.0 + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + ora@3.4.0: + dependencies: + chalk: 2.4.2 + cli-cursor: 2.1.0 + cli-spinners: 2.9.2 + log-symbols: 2.2.0 + strip-ansi: 5.2.0 + wcwidth: 1.0.1 + + os-browserify@0.3.0: {} + + os-tmpdir@1.0.2: {} + + own-keys@1.0.1: + dependencies: + get-intrinsic: 1.3.0 + object-keys: 1.1.1 + safe-push-apply: 1.0.0 + + p-finally@1.0.0: {} + + p-finally@2.0.1: {} + + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + + p-locate@3.0.0: + dependencies: + p-limit: 2.3.0 + + p-locate@4.1.0: + dependencies: + p-limit: 2.3.0 + + p-map@2.1.0: {} + + p-map@3.0.0: + dependencies: + aggregate-error: 3.1.0 + + p-map@4.0.0: + dependencies: + aggregate-error: 3.1.0 + + p-retry@3.0.1: + dependencies: + retry: 0.12.0 + + p-try@2.2.0: {} + + pako@1.0.11: {} + + parallel-transform@1.2.0: + dependencies: + cyclist: 1.0.2 + inherits: 2.0.4 + readable-stream: 2.3.8 + + param-case@2.1.1: + dependencies: + no-case: 2.3.2 + + parchment@1.1.4: {} + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + parse-asn1@5.1.9: + dependencies: + asn1.js: 4.10.1 + browserify-aes: 1.2.0 + evp_bytestokey: 1.0.3 + pbkdf2: 3.1.5 + safe-buffer: 5.2.1 + + parse-json@4.0.0: + dependencies: + error-ex: 1.3.4 + json-parse-better-errors: 1.0.2 + + parse-json@5.2.0: + dependencies: + '@babel/code-frame': 7.29.0 + error-ex: 1.3.4 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + + parse5-htmlparser2-tree-adapter@6.0.1: + dependencies: + parse5: 6.0.1 + + parse5@5.1.1: {} + + parse5@6.0.1: {} + + parseurl@1.3.3: {} + + pascalcase@0.1.1: {} + + path-browserify@0.0.1: {} + + path-dirname@1.0.2: {} + + path-exists@2.1.0: + dependencies: + pinkie-promise: 2.0.1 + + path-exists@3.0.0: {} + + path-exists@4.0.0: {} + + path-is-absolute@1.0.1: {} + + path-is-inside@1.0.2: {} + + path-key@2.0.1: {} + + path-key@3.1.1: {} + + path-parse@1.0.7: {} + + path-to-regexp@0.1.13: {} + + path-type@3.0.0: + dependencies: + pify: 3.0.0 + + path-type@4.0.0: {} + + pbkdf2@3.1.5: + dependencies: + create-hash: 1.2.0 + create-hmac: 1.1.7 + ripemd160: 2.0.3 + safe-buffer: 5.2.1 + sha.js: 2.4.12 + to-buffer: 1.2.2 + + performance-now@2.1.0: {} + + picocolors@0.2.1: {} + + picocolors@1.1.1: {} + + picomatch@2.3.2: {} + + pify@2.3.0: {} + + pify@3.0.0: {} + + pify@4.0.1: {} + + pinkie-promise@2.0.1: + dependencies: + pinkie: 2.0.4 + + pinkie@2.0.4: {} + + pkg-dir@1.0.0: + dependencies: + find-up: 1.1.2 + + pkg-dir@3.0.0: + dependencies: + find-up: 3.0.0 + + pkg-dir@4.2.0: + dependencies: + find-up: 4.1.0 + + please-upgrade-node@3.2.0: + dependencies: + semver-compare: 1.0.0 + + pnp-webpack-plugin@1.7.0: + dependencies: + ts-pnp: 1.2.0 + transitivePeerDependencies: + - typescript + + portfinder@1.0.38(supports-color@6.1.0): + dependencies: + async: 3.2.6 + debug: 4.4.3(supports-color@6.1.0) + transitivePeerDependencies: + - supports-color + + posix-character-classes@0.1.1: {} + + possible-typed-array-names@1.1.0: {} + + postcss-calc@7.0.5: + dependencies: + postcss: 7.0.39 + postcss-selector-parser: 6.1.2 + postcss-value-parser: 4.2.0 + + postcss-colormin@4.0.3: + dependencies: + browserslist: 4.28.2 + color: 3.2.1 + has: 1.0.4 + postcss: 7.0.39 + postcss-value-parser: 3.3.1 + + postcss-convert-values@4.0.1: + dependencies: + postcss: 7.0.39 + postcss-value-parser: 3.3.1 + + postcss-discard-comments@4.0.2: + dependencies: + postcss: 7.0.39 + + postcss-discard-duplicates@4.0.2: + dependencies: + postcss: 7.0.39 + + postcss-discard-empty@4.0.1: + dependencies: + postcss: 7.0.39 + + postcss-discard-overridden@4.0.1: + dependencies: + postcss: 7.0.39 + + postcss-load-config@2.1.2: + dependencies: + cosmiconfig: 5.2.1 + import-cwd: 2.1.0 + + postcss-loader@3.0.0: + dependencies: + loader-utils: 1.4.2 + postcss: 7.0.39 + postcss-load-config: 2.1.2 + schema-utils: 1.0.0 + + postcss-merge-longhand@4.0.11: + dependencies: + css-color-names: 0.0.4 + postcss: 7.0.39 + postcss-value-parser: 3.3.1 + stylehacks: 4.0.3 + + postcss-merge-rules@4.0.3: + dependencies: + browserslist: 4.28.2 + caniuse-api: 3.0.0 + cssnano-util-same-parent: 4.0.1 + postcss: 7.0.39 + postcss-selector-parser: 3.1.2 + vendors: 1.0.4 + + postcss-minify-font-values@4.0.2: + dependencies: + postcss: 7.0.39 + postcss-value-parser: 3.3.1 + + postcss-minify-gradients@4.0.2: + dependencies: + cssnano-util-get-arguments: 4.0.0 + is-color-stop: 1.1.0 + postcss: 7.0.39 + postcss-value-parser: 3.3.1 + + postcss-minify-params@4.0.2: + dependencies: + alphanum-sort: 1.0.2 + browserslist: 4.28.2 + cssnano-util-get-arguments: 4.0.0 + postcss: 7.0.39 + postcss-value-parser: 3.3.1 + uniqs: 2.0.0 + + postcss-minify-selectors@4.0.2: + dependencies: + alphanum-sort: 1.0.2 + has: 1.0.4 + postcss: 7.0.39 + postcss-selector-parser: 3.1.2 + + postcss-modules-extract-imports@2.0.0: + dependencies: + postcss: 7.0.39 + + postcss-modules-local-by-default@3.0.3: + dependencies: + icss-utils: 4.1.1 + postcss: 7.0.39 + postcss-selector-parser: 6.1.2 + postcss-value-parser: 4.2.0 + + postcss-modules-scope@2.2.0: + dependencies: + postcss: 7.0.39 + postcss-selector-parser: 6.1.2 + + postcss-modules-values@3.0.0: + dependencies: + icss-utils: 4.1.1 + postcss: 7.0.39 + + postcss-normalize-charset@4.0.1: + dependencies: + postcss: 7.0.39 + + postcss-normalize-display-values@4.0.2: + dependencies: + cssnano-util-get-match: 4.0.0 + postcss: 7.0.39 + postcss-value-parser: 3.3.1 + + postcss-normalize-positions@4.0.2: + dependencies: + cssnano-util-get-arguments: 4.0.0 + has: 1.0.4 + postcss: 7.0.39 + postcss-value-parser: 3.3.1 + + postcss-normalize-repeat-style@4.0.2: + dependencies: + cssnano-util-get-arguments: 4.0.0 + cssnano-util-get-match: 4.0.0 + postcss: 7.0.39 + postcss-value-parser: 3.3.1 + + postcss-normalize-string@4.0.2: + dependencies: + has: 1.0.4 + postcss: 7.0.39 + postcss-value-parser: 3.3.1 + + postcss-normalize-timing-functions@4.0.2: + dependencies: + cssnano-util-get-match: 4.0.0 + postcss: 7.0.39 + postcss-value-parser: 3.3.1 + + postcss-normalize-unicode@4.0.1: + dependencies: + browserslist: 4.28.2 + postcss: 7.0.39 + postcss-value-parser: 3.3.1 + + postcss-normalize-url@4.0.1: + dependencies: + is-absolute-url: 2.1.0 + normalize-url: 3.3.0 + postcss: 7.0.39 + postcss-value-parser: 3.3.1 + + postcss-normalize-whitespace@4.0.2: + dependencies: + postcss: 7.0.39 + postcss-value-parser: 3.3.1 + + postcss-ordered-values@4.1.2: + dependencies: + cssnano-util-get-arguments: 4.0.0 + postcss: 7.0.39 + postcss-value-parser: 3.3.1 + + postcss-prefix-selector@1.16.1(postcss@5.2.18): + dependencies: + postcss: 5.2.18 + + postcss-reduce-initial@4.0.3: + dependencies: + browserslist: 4.28.2 + caniuse-api: 3.0.0 + has: 1.0.4 + postcss: 7.0.39 + + postcss-reduce-transforms@4.0.2: + dependencies: + cssnano-util-get-match: 4.0.0 + has: 1.0.4 + postcss: 7.0.39 + postcss-value-parser: 3.3.1 + + postcss-selector-parser@3.1.2: + dependencies: + dot-prop: 5.3.0 + indexes-of: 1.0.1 + uniq: 1.0.1 + + postcss-selector-parser@6.1.2: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-svgo@4.0.3: + dependencies: + postcss: 7.0.39 + postcss-value-parser: 3.3.1 + svgo: 1.3.2 + + postcss-unique-selectors@4.0.1: + dependencies: + alphanum-sort: 1.0.2 + postcss: 7.0.39 + uniqs: 2.0.0 + + postcss-value-parser@3.3.1: {} + + postcss-value-parser@4.2.0: {} + + postcss@5.2.18: + dependencies: + chalk: 1.1.3 + js-base64: 2.6.4 + source-map: 0.5.7 + supports-color: 3.2.3 + + postcss@7.0.39: + dependencies: + picocolors: 0.2.1 + source-map: 0.6.1 + + postcss@8.5.10: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + posthtml-parser@0.2.1: + dependencies: + htmlparser2: 3.10.1 + isobject: 2.1.0 + + posthtml-rename-id@1.0.12: + dependencies: + escape-string-regexp: 1.0.5 + + posthtml-render@1.4.0: {} + + posthtml-svg-mode@1.0.3: + dependencies: + merge-options: 1.0.1 + posthtml: 0.9.2 + posthtml-parser: 0.2.1 + posthtml-render: 1.4.0 + + posthtml@0.9.2: + dependencies: + posthtml-parser: 0.2.1 + posthtml-render: 1.4.0 + + prelude-ls@1.2.1: {} + + prepend-http@1.0.4: {} + + prettier@2.8.8: + optional: true + + pretty-error@2.1.2: + dependencies: + lodash: 4.18.1 + renderkid: 2.0.7 + + process-nextick-args@2.0.1: {} + + process@0.11.10: {} + + progress@2.0.3: {} + + promise-inflight@1.0.1(bluebird@3.7.2): + optionalDependencies: + bluebird: 3.7.2 + + proto-list@1.2.4: {} + + proxy-addr@2.0.7: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + + proxy-from-env@1.1.0: {} + + prr@1.0.1: {} + + pseudomap@1.0.2: {} + + psl@1.15.0: + dependencies: + punycode: 2.3.1 + + public-encrypt@4.0.3: + dependencies: + bn.js: 4.12.3 + browserify-rsa: 4.1.1 + create-hash: 1.2.0 + parse-asn1: 5.1.9 + randombytes: 2.1.0 + safe-buffer: 5.2.1 + + pump@2.0.1: + dependencies: + end-of-stream: 1.4.5 + once: 1.4.0 + + pump@3.0.4: + dependencies: + end-of-stream: 1.4.5 + once: 1.4.0 + + pumpify@1.5.1: + dependencies: + duplexify: 3.7.1 + inherits: 2.0.4 + pump: 2.0.1 + + punycode@1.4.1: {} + + punycode@2.3.1: {} + + q@1.5.1: {} + + qs@6.14.2: + dependencies: + side-channel: 1.1.0 + + qs@6.15.1: + dependencies: + side-channel: 1.1.0 + + qs@6.5.5: {} + + query-string@4.3.4: + dependencies: + object-assign: 4.1.1 + strict-uri-encode: 1.1.0 + + querystring-es3@0.2.1: {} + + querystringify@2.2.0: {} + + quill-delta@3.6.3: + dependencies: + deep-equal: 1.1.2 + extend: 3.0.2 + fast-diff: 1.1.2 + + quill@1.3.7: + dependencies: + clone: 2.1.2 + deep-equal: 1.1.2 + eventemitter3: 2.0.3 + extend: 3.0.2 + parchment: 1.1.4 + quill-delta: 3.6.3 + + randombytes@2.1.0: + dependencies: + safe-buffer: 5.2.1 + + randomfill@1.0.4: + dependencies: + randombytes: 2.1.0 + safe-buffer: 5.2.1 + + range-parser@1.2.1: {} + + raw-body@2.5.3: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.1 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + + read-pkg@5.2.0: + dependencies: + '@types/normalize-package-data': 2.4.4 + normalize-package-data: 2.5.0 + parse-json: 5.2.0 + type-fest: 0.6.0 + + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + + readdirp@2.2.1(supports-color@6.1.0): + dependencies: + graceful-fs: 4.2.11 + micromatch: 3.1.10(supports-color@6.1.0) + readable-stream: 2.3.8 + transitivePeerDependencies: + - supports-color + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.2 + + reflect.getprototypeof@1.0.10: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + which-builtin-type: 1.2.1 + + regenerate-unicode-properties@10.2.2: + dependencies: + regenerate: 1.4.2 + + regenerate@1.4.2: {} + + regenerator-runtime@0.11.1: {} + + regex-not@1.0.2: + dependencies: + extend-shallow: 3.0.2 + safe-regex: 1.1.0 + + regexp.prototype.flags@1.5.4: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-errors: 1.3.0 + get-proto: 1.0.1 + gopd: 1.2.0 + set-function-name: 2.0.2 + + regexpp@3.2.0: {} + + regexpu-core@6.4.0: + dependencies: + regenerate: 1.4.2 + regenerate-unicode-properties: 10.2.2 + regjsgen: 0.8.0 + regjsparser: 0.13.1 + unicode-match-property-ecmascript: 2.0.0 + unicode-match-property-value-ecmascript: 2.2.1 + + regjsgen@0.8.0: {} + + regjsparser@0.13.1: + dependencies: + jsesc: 3.1.0 + + relateurl@0.2.7: {} + + remove-trailing-separator@1.1.0: {} + + renderkid@2.0.7: + dependencies: + css-select: 4.3.0 + dom-converter: 0.2.0 + htmlparser2: 6.1.0 + lodash: 4.18.1 + strip-ansi: 3.0.1 + + repeat-element@1.1.4: {} + + repeat-string@1.6.1: {} + + request@2.88.2: + dependencies: + aws-sign2: 0.7.0 + aws4: 1.13.2 + caseless: 0.12.0 + combined-stream: 1.0.8 + extend: 3.0.2 + forever-agent: 0.6.1 + form-data: 2.3.3 + har-validator: 5.1.5 + http-signature: 1.2.0 + is-typedarray: 1.0.0 + isstream: 0.1.2 + json-stringify-safe: 5.0.1 + mime-types: 2.1.35 + oauth-sign: 0.9.0 + performance-now: 2.1.0 + qs: 6.5.5 + safe-buffer: 5.2.1 + tough-cookie: 2.5.0 + tunnel-agent: 0.6.0 + uuid: 3.4.0 + + require-directory@2.1.1: {} + + require-main-filename@2.0.0: {} + + requires-port@1.0.0: {} + + resize-observer-polyfill@1.5.1: {} + + resolve-cwd@2.0.0: + dependencies: + resolve-from: 3.0.0 + + resolve-from@3.0.0: {} + + resolve-from@4.0.0: {} + + resolve-url@0.2.1: {} + + resolve@1.22.12: + dependencies: + es-errors: 1.3.0 + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + restore-cursor@2.0.0: + dependencies: + onetime: 2.0.1 + signal-exit: 3.0.7 + + restore-cursor@3.1.0: + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + + ret@0.1.15: {} + + retry@0.12.0: {} + + rfdc@1.4.1: {} + + rgb-regex@1.0.1: {} + + rgba-regex@1.0.0: {} + + rimraf@2.7.1: + dependencies: + glob: 7.2.3 + + rimraf@3.0.2: + dependencies: + glob: 7.2.3 + + ripemd160@2.0.3: + dependencies: + hash-base: 3.1.2 + inherits: 2.0.4 + + run-async@2.4.1: {} + + run-queue@1.0.3: + dependencies: + aproba: 1.2.0 + + runjs@4.4.2: + dependencies: + chalk: 2.3.0 + lodash.padend: 4.6.1 + microcli: 1.3.3 + omelette: 0.4.5 + + rxjs@6.6.7: + dependencies: + tslib: 1.14.1 + + rxjs@7.8.2: + dependencies: + tslib: 2.8.1 + + safe-array-concat@1.1.4: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + has-symbols: 1.1.0 + isarray: 2.0.5 + + safe-buffer@5.1.2: {} + + safe-buffer@5.2.1: {} + + safe-push-apply@1.0.0: + dependencies: + es-errors: 1.3.0 + isarray: 2.0.5 + + safe-regex-test@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-regex: 1.2.1 + + safe-regex@1.1.0: + dependencies: + ret: 0.1.15 + + safer-buffer@2.1.2: {} + + sass-loader@10.1.1(sass@1.32.13)(webpack@4.47.0): + dependencies: + klona: 2.0.6 + loader-utils: 2.0.4 + neo-async: 2.6.2 + schema-utils: 3.3.0 + semver: 7.7.4 + webpack: 4.47.0 + optionalDependencies: + sass: 1.32.13 + + sass@1.32.13: + dependencies: + chokidar: 3.6.0 + + sax@1.2.4: {} + + schema-utils@1.0.0: + dependencies: + ajv: 6.15.0 + ajv-errors: 1.0.1(ajv@6.15.0) + ajv-keywords: 3.5.2(ajv@6.15.0) + + schema-utils@2.7.1: + dependencies: + '@types/json-schema': 7.0.15 + ajv: 6.15.0 + ajv-keywords: 3.5.2(ajv@6.15.0) + + schema-utils@3.3.0: + dependencies: + '@types/json-schema': 7.0.15 + ajv: 6.15.0 + ajv-keywords: 3.5.2(ajv@6.15.0) + + screenfull@5.0.2: {} + + script-ext-html-webpack-plugin@2.1.5(html-webpack-plugin@3.2.0(webpack@4.47.0))(webpack@4.47.0): + dependencies: + debug: 4.4.3(supports-color@6.1.0) + html-webpack-plugin: 3.2.0(webpack@4.47.0) + webpack: 4.47.0 + transitivePeerDependencies: + - supports-color + + select-hose@2.0.0: {} + + select@1.1.2: {} + + selfsigned@1.10.14: + dependencies: + node-forge: 0.10.0 + + semver-compare@1.0.0: {} + + semver@5.7.2: {} + + semver@6.3.1: {} + + semver@7.7.4: {} + + send@0.19.2(supports-color@6.1.0): + dependencies: + debug: 2.6.9(supports-color@6.1.0) + depd: 2.0.0 + destroy: 1.2.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 0.5.2 + http-errors: 2.0.1 + mime: 1.6.0 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + + serialize-javascript@4.0.0: + dependencies: + randombytes: 2.1.0 + + serialize-javascript@5.0.1: + dependencies: + randombytes: 2.1.0 + + serve-index@1.9.2(supports-color@6.1.0): + dependencies: + accepts: 1.3.8 + batch: 0.6.1 + debug: 2.6.9(supports-color@6.1.0) + escape-html: 1.0.3 + http-errors: 1.8.1 + mime-types: 2.1.35 + parseurl: 1.3.3 + transitivePeerDependencies: + - supports-color + + serve-static@1.16.3(supports-color@6.1.0): + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 0.19.2(supports-color@6.1.0) + transitivePeerDependencies: + - supports-color + + set-blocking@2.0.0: {} + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + + set-function-name@2.0.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + + set-proto@1.0.0: + dependencies: + dunder-proto: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + + set-value@2.0.1: + dependencies: + extend-shallow: 2.0.1 + is-extendable: 0.1.1 + is-plain-object: 2.0.4 + split-string: 3.1.0 + + setimmediate@1.0.5: {} + + setprototypeof@1.2.0: {} + + sha.js@2.4.12: + dependencies: + inherits: 2.0.4 + safe-buffer: 5.2.1 + to-buffer: 1.2.2 + + shebang-command@1.2.0: + dependencies: + shebang-regex: 1.0.0 + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@1.0.0: {} + + shebang-regex@3.0.0: {} + + shell-quote@1.8.3: {} + + side-channel-list@1.0.1: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.1 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + + sigmund@1.0.1: {} + + signal-exit@3.0.7: {} + + simple-swizzle@0.2.4: + dependencies: + is-arrayish: 0.3.4 + + slash@1.0.0: {} + + slash@2.0.0: {} + + slice-ansi@2.1.0: + dependencies: + ansi-styles: 3.2.1 + astral-regex: 1.0.0 + is-fullwidth-code-point: 2.0.0 + + slice-ansi@3.0.0: + dependencies: + ansi-styles: 4.3.0 + astral-regex: 2.0.0 + is-fullwidth-code-point: 3.0.0 + + slice-ansi@4.0.0: + dependencies: + ansi-styles: 4.3.0 + astral-regex: 2.0.0 + is-fullwidth-code-point: 3.0.0 + + snapdragon-node@2.1.1: + dependencies: + define-property: 1.0.0 + isobject: 3.0.1 + snapdragon-util: 3.0.1 + + snapdragon-util@3.0.1: + dependencies: + kind-of: 3.2.2 + + snapdragon@0.8.2(supports-color@6.1.0): + dependencies: + base: 0.11.2 + debug: 2.6.9(supports-color@6.1.0) + define-property: 0.2.5 + extend-shallow: 2.0.1 + map-cache: 0.2.2 + source-map: 0.5.7 + source-map-resolve: 0.5.3 + use: 3.1.1 + transitivePeerDependencies: + - supports-color + + sockjs-client@1.6.1(supports-color@6.1.0): + dependencies: + debug: 3.2.7(supports-color@6.1.0) + eventsource: 2.0.2 + faye-websocket: 0.11.4 + inherits: 2.0.4 + url-parse: 1.5.10 + transitivePeerDependencies: + - supports-color + + sockjs@0.3.24: + dependencies: + faye-websocket: 0.11.4 + uuid: 8.3.2 + websocket-driver: 0.7.4 + + sort-keys@1.1.2: + dependencies: + is-plain-obj: 1.1.0 + + sortablejs@1.10.2: {} + + source-list-map@2.0.1: {} + + source-map-js@1.2.1: {} + + source-map-resolve@0.5.3: + dependencies: + atob: 2.1.2 + decode-uri-component: 0.2.2 + resolve-url: 0.2.1 + source-map-url: 0.4.1 + urix: 0.1.0 + + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map-url@0.4.1: {} + + source-map@0.5.7: {} + + source-map@0.6.1: {} + + spdx-correct@3.2.0: + dependencies: + spdx-expression-parse: 3.0.1 + spdx-license-ids: 3.0.23 + + spdx-exceptions@2.5.0: {} + + spdx-expression-parse@3.0.1: + dependencies: + spdx-exceptions: 2.5.0 + spdx-license-ids: 3.0.23 + + spdx-license-ids@3.0.23: {} + + spdy-transport@3.0.0(supports-color@6.1.0): + dependencies: + debug: 4.4.3(supports-color@6.1.0) + detect-node: 2.1.0 + hpack.js: 2.1.6 + obuf: 1.1.2 + readable-stream: 3.6.2 + wbuf: 1.7.3 + transitivePeerDependencies: + - supports-color + + spdy@4.0.2(supports-color@6.1.0): + dependencies: + debug: 4.4.3(supports-color@6.1.0) + handle-thing: 2.0.1 + http-deceiver: 1.2.7 + select-hose: 2.0.0 + spdy-transport: 3.0.0(supports-color@6.1.0) + transitivePeerDependencies: + - supports-color + + split-string@3.1.0: + dependencies: + extend-shallow: 3.0.2 + + sprintf-js@1.0.3: {} + + sshpk@1.18.0: + dependencies: + asn1: 0.2.6 + assert-plus: 1.0.0 + bcrypt-pbkdf: 1.0.2 + dashdash: 1.14.1 + ecc-jsbn: 0.1.2 + getpass: 0.1.7 + jsbn: 0.1.1 + safer-buffer: 2.1.2 + tweetnacl: 0.14.5 + + ssri@6.0.2: + dependencies: + figgy-pudding: 3.5.2 + + ssri@7.1.1: + dependencies: + figgy-pudding: 3.5.2 + minipass: 3.3.6 + + ssri@8.0.1: + dependencies: + minipass: 3.3.6 + + stable@0.1.8: {} + + stackframe@1.3.4: {} + + static-extend@0.1.2: + dependencies: + define-property: 0.2.5 + object-copy: 0.1.0 + + statuses@1.3.1: {} + + statuses@1.5.0: {} + + statuses@2.0.2: {} + + stop-iteration-iterator@1.1.0: + dependencies: + es-errors: 1.3.0 + internal-slot: 1.1.0 + + stream-browserify@2.0.2: + dependencies: + inherits: 2.0.4 + readable-stream: 2.3.8 + + stream-each@1.2.3: + dependencies: + end-of-stream: 1.4.5 + stream-shift: 1.0.3 + + stream-http@2.8.3: + dependencies: + builtin-status-codes: 3.0.0 + inherits: 2.0.4 + readable-stream: 2.3.8 + to-arraybuffer: 1.0.1 + xtend: 4.0.2 + + stream-shift@1.0.3: {} + + strict-uri-encode@1.1.0: {} + + string-argv@0.3.1: {} + + string-width@3.1.0: + dependencies: + emoji-regex: 7.0.3 + is-fullwidth-code-point: 2.0.0 + strip-ansi: 5.2.0 + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string.prototype.trim@1.2.10: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-data-property: 1.1.4 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-object-atoms: 1.1.1 + has-property-descriptors: 1.0.2 + + string.prototype.trimend@1.0.9: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + string.prototype.trimstart@1.0.8: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + stringify-object@3.3.0: + dependencies: + get-own-enumerable-property-symbols: 3.0.2 + is-obj: 1.0.1 + is-regexp: 1.0.0 + + strip-ansi@3.0.1: + dependencies: + ansi-regex: 2.1.1 + + strip-ansi@5.2.0: + dependencies: + ansi-regex: 4.1.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-eof@1.0.0: {} + + strip-final-newline@2.0.0: {} + + strip-indent@2.0.0: {} + + strip-json-comments@3.1.1: {} + + stylehacks@4.0.3: + dependencies: + browserslist: 4.28.2 + postcss: 7.0.39 + postcss-selector-parser: 3.1.2 + + supports-color@2.0.0: {} + + supports-color@3.2.3: + dependencies: + has-flag: 1.0.0 + + supports-color@4.5.0: + dependencies: + has-flag: 2.0.0 + + supports-color@5.5.0: + dependencies: + has-flag: 3.0.0 + + supports-color@6.1.0: + dependencies: + has-flag: 3.0.0 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + svg-baker-runtime@1.4.7: + dependencies: + deepmerge: 1.3.2 + mitt: 1.1.2 + svg-baker: 1.7.0 + transitivePeerDependencies: + - supports-color + + svg-baker@1.7.0: + dependencies: + bluebird: 3.7.2 + clone: 2.1.2 + he: 1.2.0 + image-size: 0.5.5 + loader-utils: 1.4.2 + merge-options: 1.0.1 + micromatch: 3.1.0 + postcss: 5.2.18 + postcss-prefix-selector: 1.16.1(postcss@5.2.18) + posthtml-rename-id: 1.0.12 + posthtml-svg-mode: 1.0.3 + query-string: 4.3.4 + traverse: 0.6.11 + transitivePeerDependencies: + - supports-color + + svg-sprite-loader@5.1.1(webpack@4.47.0): + dependencies: + bluebird: 3.7.2 + deepmerge: 1.3.2 + domready: 1.0.8 + escape-string-regexp: 1.0.5 + html-webpack-plugin: 3.2.0(webpack@4.47.0) + loader-utils: 1.4.2 + svg-baker: 1.7.0 + svg-baker-runtime: 1.4.7 + url-slug: 2.0.0 + transitivePeerDependencies: + - supports-color + - webpack + + svg-tags@1.0.0: {} + + svgo@1.3.2: + dependencies: + chalk: 2.4.2 + coa: 2.0.2 + css-select: 2.1.0 + css-select-base-adapter: 0.1.1 + css-tree: 1.0.0-alpha.37 + csso: 4.2.0 + js-yaml: 3.14.2 + mkdirp: 0.5.6 + object.values: 1.2.1 + sax: 1.2.4 + stable: 0.1.8 + unquote: 1.1.1 + util.promisify: 1.0.1 + + table@5.4.6: + dependencies: + ajv: 6.15.0 + lodash: 4.18.1 + slice-ansi: 2.1.0 + string-width: 3.1.0 + + tapable@1.1.3: {} + + tar@6.2.1: + dependencies: + chownr: 2.0.0 + fs-minipass: 2.1.0 + minipass: 5.0.0 + minizlib: 2.1.2 + mkdirp: 1.0.4 + yallist: 4.0.0 + + terser-webpack-plugin@1.4.6(webpack@4.47.0): + dependencies: + cacache: 12.0.4 + find-cache-dir: 2.1.0 + is-wsl: 1.1.0 + schema-utils: 1.0.0 + serialize-javascript: 4.0.0 + source-map: 0.6.1 + terser: 4.8.1 + webpack: 4.47.0 + webpack-sources: 1.4.3 + worker-farm: 1.7.0 + + terser-webpack-plugin@2.3.8(webpack@4.47.0): + dependencies: + cacache: 13.0.1 + find-cache-dir: 3.3.2 + jest-worker: 25.5.0 + p-limit: 2.3.0 + schema-utils: 2.7.1 + serialize-javascript: 4.0.0 + source-map: 0.6.1 + terser: 4.8.1 + webpack: 4.47.0 + webpack-sources: 1.4.3 + transitivePeerDependencies: + - bluebird + + terser@4.8.1: + dependencies: + acorn: 8.16.0 + commander: 2.20.3 + source-map: 0.6.1 + source-map-support: 0.5.21 + + text-table@0.2.0: {} + + thenify-all@1.6.0: + dependencies: + thenify: 3.3.1 + + thenify@3.3.1: + dependencies: + any-promise: 1.3.0 + + thread-loader@2.1.3(webpack@4.47.0): + dependencies: + loader-runner: 2.4.0 + loader-utils: 1.4.2 + neo-async: 2.6.2 + webpack: 4.47.0 + + throttle-debounce@1.1.0: {} + + through2@2.0.5: + dependencies: + readable-stream: 2.3.8 + xtend: 4.0.2 + + through@2.3.8: {} + + thunky@1.1.0: {} + + timers-browserify@2.0.12: + dependencies: + setimmediate: 1.0.5 + + timsort@0.3.0: {} + + tiny-emitter@2.1.0: {} + + tmp@0.0.33: + dependencies: + os-tmpdir: 1.0.2 + + to-arraybuffer@1.0.1: {} + + to-buffer@1.2.2: + dependencies: + isarray: 2.0.5 + safe-buffer: 5.2.1 + typed-array-buffer: 1.0.3 + + to-object-path@0.3.0: + dependencies: + kind-of: 3.2.2 + + to-regex-range@2.1.1: + dependencies: + is-number: 3.0.0 + repeat-string: 1.6.1 + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + to-regex@3.0.2: + dependencies: + define-property: 2.0.2 + extend-shallow: 3.0.2 + regex-not: 1.0.2 + safe-regex: 1.1.0 + + toidentifier@1.0.1: {} + + toposort@1.0.7: {} + + tough-cookie@2.5.0: + dependencies: + psl: 1.15.0 + punycode: 2.3.1 + + traverse@0.6.11: + dependencies: + gopd: 1.2.0 + typedarray.prototype.slice: 1.0.5 + which-typed-array: 1.1.20 + + tryer@1.0.1: {} + + ts-pnp@1.2.0: {} + + tslib@1.14.1: {} + + tslib@2.3.0: {} + + tslib@2.8.1: {} + + tty-browserify@0.0.0: {} + + tunnel-agent@0.6.0: + dependencies: + safe-buffer: 5.2.1 + + tweetnacl@0.14.5: {} + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + type-fest@0.21.3: {} + + type-fest@0.6.0: {} + + type-fest@0.8.1: {} + + type-is@1.6.18: + dependencies: + media-typer: 0.3.0 + mime-types: 2.1.35 + + typed-array-buffer@1.0.3: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-typed-array: 1.1.15 + + typed-array-byte-length@1.0.3: + dependencies: + call-bind: 1.0.9 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + + typed-array-byte-offset@1.0.4: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.9 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + reflect.getprototypeof: 1.0.10 + + typed-array-length@1.0.7: + dependencies: + call-bind: 1.0.9 + for-each: 0.3.5 + gopd: 1.2.0 + is-typed-array: 1.1.15 + possible-typed-array-names: 1.1.0 + reflect.getprototypeof: 1.0.10 + + typedarray.prototype.slice@1.0.5: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + get-proto: 1.0.1 + math-intrinsics: 1.1.0 + typed-array-buffer: 1.0.3 + typed-array-byte-offset: 1.0.4 + + typedarray@0.0.6: {} + + uglify-js@3.4.10: + dependencies: + commander: 2.19.0 + source-map: 0.6.1 + + unbox-primitive@1.1.0: + dependencies: + call-bound: 1.0.4 + has-bigints: 1.1.0 + has-symbols: 1.1.0 + which-boxed-primitive: 1.1.1 + + undici-types@7.19.2: {} + + unicode-canonical-property-names-ecmascript@2.0.1: {} + + unicode-match-property-ecmascript@2.0.0: + dependencies: + unicode-canonical-property-names-ecmascript: 2.0.1 + unicode-property-aliases-ecmascript: 2.2.0 + + unicode-match-property-value-ecmascript@2.2.1: {} + + unicode-property-aliases-ecmascript@2.2.0: {} + + unidecode@0.1.8: {} + + union-value@1.0.1: + dependencies: + arr-union: 3.1.0 + get-value: 2.0.6 + is-extendable: 0.1.1 + set-value: 2.0.1 + + uniq@1.0.1: {} + + uniqs@2.0.0: {} + + unique-filename@1.1.1: + dependencies: + unique-slug: 2.0.2 + + unique-slug@2.0.2: + dependencies: + imurmurhash: 0.1.4 + + universalify@0.1.2: {} + + unpipe@1.0.0: {} + + unquote@1.1.1: {} + + unset-value@1.0.0: + dependencies: + has-value: 0.3.1 + isobject: 3.0.1 + + upath@1.2.0: {} + + update-browserslist-db@1.2.3(browserslist@4.28.2): + dependencies: + browserslist: 4.28.2 + escalade: 3.2.0 + picocolors: 1.1.1 + + upper-case@1.1.3: {} + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + urix@0.1.0: {} + + url-loader@2.3.0(file-loader@4.3.0(webpack@4.47.0))(webpack@4.47.0): + dependencies: + loader-utils: 1.4.2 + mime: 2.6.0 + schema-utils: 2.7.1 + webpack: 4.47.0 + optionalDependencies: + file-loader: 4.3.0(webpack@4.47.0) + + url-parse@1.5.10: + dependencies: + querystringify: 2.2.0 + requires-port: 1.0.0 + + url-slug@2.0.0: + dependencies: + unidecode: 0.1.8 + + url@0.11.4: + dependencies: + punycode: 1.4.1 + qs: 6.15.1 + + use@3.1.1: {} + + util-deprecate@1.0.2: {} + + util.promisify@1.0.0: + dependencies: + define-properties: 1.2.1 + object.getownpropertydescriptors: 2.1.9 + + util.promisify@1.0.1: + dependencies: + define-properties: 1.2.1 + es-abstract: 1.24.2 + has-symbols: 1.1.0 + object.getownpropertydescriptors: 2.1.9 + + util@0.10.4: + dependencies: + inherits: 2.0.3 + + util@0.11.1: + dependencies: + inherits: 2.0.3 + + utila@0.4.0: {} + + utils-merge@1.0.1: {} + + uuid@3.4.0: {} + + uuid@8.3.2: {} + + v8-compile-cache@2.4.0: {} + + validate-npm-package-license@3.0.4: + dependencies: + spdx-correct: 3.2.0 + spdx-expression-parse: 3.0.1 + + vary@1.1.2: {} + + vendors@1.0.4: {} + + verror@1.10.0: + dependencies: + assert-plus: 1.0.0 + core-util-is: 1.0.2 + extsprintf: 1.3.0 + + vm-browserify@1.1.2: {} + + vue-count-to@1.0.13: {} + + vue-cropper@0.5.5: {} + + vue-eslint-parser@7.11.0(eslint@7.15.0): + dependencies: + debug: 4.4.3(supports-color@6.1.0) + eslint: 7.15.0 + eslint-scope: 5.1.1 + eslint-visitor-keys: 1.3.0 + espree: 6.2.1 + esquery: 1.7.0 + lodash: 4.18.1 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + vue-hot-reload-api@2.3.4: {} + + vue-loader@15.11.1(@vue/compiler-sfc@3.5.33)(cache-loader@4.1.0(webpack@4.47.0))(css-loader@3.6.0(webpack@4.47.0))(lodash@4.18.1)(vue-template-compiler@2.6.12)(webpack@4.47.0): + dependencies: + '@vue/component-compiler-utils': 3.3.0(lodash@4.18.1) + css-loader: 3.6.0(webpack@4.47.0) + hash-sum: 1.0.2 + loader-utils: 1.4.2 + vue-hot-reload-api: 2.3.4 + vue-style-loader: 4.1.3 + webpack: 4.47.0 + optionalDependencies: + '@vue/compiler-sfc': 3.5.33 + cache-loader: 4.1.0(webpack@4.47.0) + vue-template-compiler: 2.6.12 + transitivePeerDependencies: + - arc-templates + - atpl + - babel-core + - bracket-template + - coffee-script + - dot + - dust + - dustjs-helpers + - dustjs-linkedin + - eco + - ect + - ejs + - haml-coffee + - hamlet + - hamljs + - handlebars + - hogan.js + - htmling + - jade + - jazz + - jqtpl + - just + - liquid-node + - liquor + - lodash + - marko + - mote + - mustache + - nunjucks + - plates + - pug + - qejs + - ractive + - razor-tmpl + - react + - react-dom + - slm + - squirrelly + - swig + - swig-templates + - teacup + - templayed + - then-jade + - then-pug + - tinyliquid + - toffee + - twig + - twing + - underscore + - vash + - velocityjs + - walrus + - whiskers + + vue-meta@2.4.0: + dependencies: + deepmerge: 4.3.1 + + vue-router@3.4.9(vue@2.6.12): + dependencies: + vue: 2.6.12 + + vue-style-loader@4.1.3: + dependencies: + hash-sum: 1.0.2 + loader-utils: 1.4.2 + + vue-template-compiler@2.6.12: + dependencies: + de-indent: 1.0.2 + he: 1.2.0 + + vue-template-es2015-compiler@1.9.1: {} + + vue@2.6.12: {} + + vuedraggable@2.24.3: + dependencies: + sortablejs: 1.10.2 + + vuex@3.6.0(vue@2.6.12): + dependencies: + vue: 2.6.12 + + watch-size@2.0.0: {} + + watchpack-chokidar2@2.0.1: + dependencies: + chokidar: 2.1.8(supports-color@6.1.0) + transitivePeerDependencies: + - supports-color + optional: true + + watchpack@1.7.5: + dependencies: + graceful-fs: 4.2.11 + neo-async: 2.6.2 + optionalDependencies: + chokidar: 3.6.0 + watchpack-chokidar2: 2.0.1 + transitivePeerDependencies: + - supports-color + + wbuf@1.7.3: + dependencies: + minimalistic-assert: 1.0.1 + + wcwidth@1.0.1: + dependencies: + defaults: 1.0.4 + + webpack-bundle-analyzer@3.9.0: + dependencies: + acorn: 7.4.1 + acorn-walk: 7.2.0 + bfj: 6.1.2 + chalk: 2.4.2 + commander: 2.20.3 + ejs: 2.7.4 + express: 4.22.1(supports-color@6.1.0) + filesize: 3.6.1 + gzip-size: 5.1.1 + lodash: 4.18.1 + mkdirp: 0.5.6 + opener: 1.5.2 + ws: 6.2.3 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + webpack-chain@6.5.1: + dependencies: + deepmerge: 1.5.2 + javascript-stringify: 2.1.0 + + webpack-dev-middleware@3.7.3(webpack@4.47.0): + dependencies: + memory-fs: 0.4.1 + mime: 2.6.0 + mkdirp: 0.5.6 + range-parser: 1.2.1 + webpack: 4.47.0 + webpack-log: 2.0.0 + + webpack-dev-server@3.11.3(webpack@4.47.0): + dependencies: + ansi-html-community: 0.0.8 + bonjour: 3.5.1 + chokidar: 2.1.8(supports-color@6.1.0) + compression: 1.8.1(supports-color@6.1.0) + connect-history-api-fallback: 1.6.0 + debug: 4.4.3(supports-color@6.1.0) + del: 4.1.1 + express: 4.22.1(supports-color@6.1.0) + html-entities: 1.4.0 + http-proxy-middleware: 0.19.1(debug@4.4.3)(supports-color@6.1.0) + import-local: 2.0.0 + internal-ip: 4.3.0 + ip: 1.1.9 + is-absolute-url: 3.0.3 + killable: 1.0.1 + loglevel: 1.9.2 + opn: 5.5.0 + p-retry: 3.0.1 + portfinder: 1.0.38(supports-color@6.1.0) + schema-utils: 1.0.0 + selfsigned: 1.10.14 + semver: 6.3.1 + serve-index: 1.9.2(supports-color@6.1.0) + sockjs: 0.3.24 + sockjs-client: 1.6.1(supports-color@6.1.0) + spdy: 4.0.2(supports-color@6.1.0) + strip-ansi: 3.0.1 + supports-color: 6.1.0 + url: 0.11.4 + webpack: 4.47.0 + webpack-dev-middleware: 3.7.3(webpack@4.47.0) + webpack-log: 2.0.0 + ws: 6.2.3 + yargs: 13.3.2 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + webpack-log@2.0.0: + dependencies: + ansi-colors: 3.2.4 + uuid: 3.4.0 + + webpack-merge@4.2.2: + dependencies: + lodash: 4.18.1 + + webpack-sources@1.4.3: + dependencies: + source-list-map: 2.0.1 + source-map: 0.6.1 + + webpack@4.47.0: + dependencies: + '@webassemblyjs/ast': 1.9.0 + '@webassemblyjs/helper-module-context': 1.9.0 + '@webassemblyjs/wasm-edit': 1.9.0 + '@webassemblyjs/wasm-parser': 1.9.0 + acorn: 6.4.2 + ajv: 6.15.0 + ajv-keywords: 3.5.2(ajv@6.15.0) + chrome-trace-event: 1.0.4 + enhanced-resolve: 4.5.0 + eslint-scope: 4.0.3 + json-parse-better-errors: 1.0.2 + loader-runner: 2.4.0 + loader-utils: 1.4.2 + memory-fs: 0.4.1 + micromatch: 3.1.10(supports-color@6.1.0) + mkdirp: 0.5.6 + neo-async: 2.6.2 + node-libs-browser: 2.2.1 + schema-utils: 1.0.0 + tapable: 1.1.3 + terser-webpack-plugin: 1.4.6(webpack@4.47.0) + watchpack: 1.7.5 + webpack-sources: 1.4.3 + transitivePeerDependencies: + - supports-color + + websocket-driver@0.7.4: + dependencies: + http-parser-js: 0.5.10 + safe-buffer: 5.2.1 + websocket-extensions: 0.1.4 + + websocket-extensions@0.1.4: {} + + which-boxed-primitive@1.1.1: + dependencies: + is-bigint: 1.1.0 + is-boolean-object: 1.2.2 + is-number-object: 1.1.1 + is-string: 1.1.1 + is-symbol: 1.1.1 + + which-builtin-type@1.2.1: + dependencies: + call-bound: 1.0.4 + function.prototype.name: 1.1.8 + has-tostringtag: 1.0.2 + is-async-function: 2.1.1 + is-date-object: 1.1.0 + is-finalizationregistry: 1.1.1 + is-generator-function: 1.1.2 + is-regex: 1.2.1 + is-weakref: 1.1.1 + isarray: 2.0.5 + which-boxed-primitive: 1.1.1 + which-collection: 1.0.2 + which-typed-array: 1.1.20 + + which-collection@1.0.2: + dependencies: + is-map: 2.0.3 + is-set: 2.0.3 + is-weakmap: 2.0.2 + is-weakset: 2.0.4 + + which-module@2.0.1: {} + + which-typed-array@1.1.20: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.9 + call-bound: 1.0.4 + for-each: 0.3.5 + get-proto: 1.0.1 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + + which@1.3.1: + dependencies: + isexe: 2.0.0 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + word-wrap@1.2.5: {} + + worker-farm@1.7.0: + dependencies: + errno: 0.1.8 + + wrap-ansi@5.1.0: + dependencies: + ansi-styles: 3.2.1 + string-width: 3.1.0 + strip-ansi: 5.2.0 + + wrap-ansi@6.2.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrappy@1.0.2: {} + + ws@6.2.3: + dependencies: + async-limiter: 1.0.1 + + xtend@4.0.2: {} + + y18n@4.0.3: {} + + y18n@5.0.8: {} + + yallist@2.1.2: {} + + yallist@3.1.1: {} + + yallist@4.0.0: {} + + yaml@1.10.3: {} + + yargs-parser@13.1.2: + dependencies: + camelcase: 5.3.1 + decamelize: 1.2.0 + + yargs-parser@20.2.9: {} + + yargs@13.3.2: + dependencies: + cliui: 5.0.0 + find-up: 3.0.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + require-main-filename: 2.0.0 + set-blocking: 2.0.0 + string-width: 3.1.0 + which-module: 2.0.1 + y18n: 4.0.3 + yargs-parser: 13.1.2 + + yargs@16.2.0: + dependencies: + cliui: 7.0.4 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 20.2.9 + + yorkie@2.0.0: + dependencies: + execa: 0.8.0 + is-ci: 1.2.1 + normalize-path: 1.0.0 + strip-indent: 2.0.0 + + zrender@5.4.0: + dependencies: + tslib: 2.3.0 diff --git a/zzyl-ui/public/favicon.ico b/zzyl-ui/public/favicon.ico new file mode 100644 index 0000000..e263760 Binary files /dev/null and b/zzyl-ui/public/favicon.ico differ diff --git a/zzyl-ui/public/html/ie.html b/zzyl-ui/public/html/ie.html new file mode 100644 index 0000000..052ffcd --- /dev/null +++ b/zzyl-ui/public/html/ie.html @@ -0,0 +1,46 @@ + + + + + + 请升级您的浏览器 + + + + + + +

请升级您的浏览器,以便我们更好的为您提供服务!

+

您正在使用 Internet Explorer 的早期版本(IE11以下版本或使用该内核的浏览器)。这意味着在升级浏览器前,您将无法访问此网站。

+
+

请注意:微软公司对Windows XP 及 Internet Explorer 早期版本的支持已经结束

+

自 2016 年 1 月 12 日起,Microsoft 不再为 IE 11 以下版本提供相应支持和更新。没有关键的浏览器安全更新,您的电脑可能易受有害病毒、间谍软件和其他恶意软件的攻击,它们可以窃取或损害您的业务数据和信息。请参阅 微软对 Internet Explorer 早期版本的支持将于 2016 年 1 月 12 日结束的说明

+
+

您可以选择更先进的浏览器

+

推荐使用以下浏览器的最新版本。如果您的电脑已有以下浏览器的最新版本则直接使用该浏览器访问即可。

+ +
+ + \ No newline at end of file diff --git a/zzyl-ui/public/index.html b/zzyl-ui/public/index.html new file mode 100644 index 0000000..925455c --- /dev/null +++ b/zzyl-ui/public/index.html @@ -0,0 +1,208 @@ + + + + + + + + + <%= webpackConfig.name %> + + + + +
+
+
+
+
+
正在加载系统资源,请耐心等待
+
+
+ + diff --git a/zzyl-ui/public/robots.txt b/zzyl-ui/public/robots.txt new file mode 100644 index 0000000..77470cb --- /dev/null +++ b/zzyl-ui/public/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Disallow: / \ No newline at end of file diff --git a/zzyl-ui/src/App.vue b/zzyl-ui/src/App.vue new file mode 100644 index 0000000..b92ea37 --- /dev/null +++ b/zzyl-ui/src/App.vue @@ -0,0 +1,28 @@ + + + + diff --git a/zzyl-ui/src/api/login.js b/zzyl-ui/src/api/login.js new file mode 100644 index 0000000..7b7388f --- /dev/null +++ b/zzyl-ui/src/api/login.js @@ -0,0 +1,60 @@ +import request from '@/utils/request' + +// 登录方法 +export function login(username, password, code, uuid) { + const data = { + username, + password, + code, + uuid + } + return request({ + url: '/login', + headers: { + isToken: false, + repeatSubmit: false + }, + method: 'post', + data: data + }) +} + +// 注册方法 +export function register(data) { + return request({ + url: '/register', + headers: { + isToken: false + }, + method: 'post', + data: data + }) +} + +// 获取用户详细信息 +export function getInfo() { + return request({ + url: '/getInfo', + method: 'get' + }) +} + +// 退出方法 +export function logout() { + return request({ + url: '/logout', + method: 'post' + }) +} + +// 获取验证码 +export function getCodeImg() { + return request({ + url: '/captchaImage', + headers: { + isToken: false + }, + method: 'get', + timeout: 20000 + }) +} \ No newline at end of file diff --git a/zzyl-ui/src/api/menu.js b/zzyl-ui/src/api/menu.js new file mode 100644 index 0000000..faef101 --- /dev/null +++ b/zzyl-ui/src/api/menu.js @@ -0,0 +1,9 @@ +import request from '@/utils/request' + +// 获取路由 +export const getRouters = () => { + return request({ + url: '/getRouters', + method: 'get' + }) +} \ No newline at end of file diff --git a/zzyl-ui/src/api/monitor/cache.js b/zzyl-ui/src/api/monitor/cache.js new file mode 100644 index 0000000..72c5f6a --- /dev/null +++ b/zzyl-ui/src/api/monitor/cache.js @@ -0,0 +1,57 @@ +import request from '@/utils/request' + +// 查询缓存详细 +export function getCache() { + return request({ + url: '/monitor/cache', + method: 'get' + }) +} + +// 查询缓存名称列表 +export function listCacheName() { + return request({ + url: '/monitor/cache/getNames', + method: 'get' + }) +} + +// 查询缓存键名列表 +export function listCacheKey(cacheName) { + return request({ + url: '/monitor/cache/getKeys/' + cacheName, + method: 'get' + }) +} + +// 查询缓存内容 +export function getCacheValue(cacheName, cacheKey) { + return request({ + url: '/monitor/cache/getValue/' + cacheName + '/' + cacheKey, + method: 'get' + }) +} + +// 清理指定名称缓存 +export function clearCacheName(cacheName) { + return request({ + url: '/monitor/cache/clearCacheName/' + cacheName, + method: 'delete' + }) +} + +// 清理指定键名缓存 +export function clearCacheKey(cacheKey) { + return request({ + url: '/monitor/cache/clearCacheKey/' + cacheKey, + method: 'delete' + }) +} + +// 清理全部缓存 +export function clearCacheAll() { + return request({ + url: '/monitor/cache/clearCacheAll', + method: 'delete' + }) +} diff --git a/zzyl-ui/src/api/monitor/job.js b/zzyl-ui/src/api/monitor/job.js new file mode 100644 index 0000000..3815569 --- /dev/null +++ b/zzyl-ui/src/api/monitor/job.js @@ -0,0 +1,71 @@ +import request from '@/utils/request' + +// 查询定时任务调度列表 +export function listJob(query) { + return request({ + url: '/monitor/job/list', + method: 'get', + params: query + }) +} + +// 查询定时任务调度详细 +export function getJob(jobId) { + return request({ + url: '/monitor/job/' + jobId, + method: 'get' + }) +} + +// 新增定时任务调度 +export function addJob(data) { + return request({ + url: '/monitor/job', + method: 'post', + data: data + }) +} + +// 修改定时任务调度 +export function updateJob(data) { + return request({ + url: '/monitor/job', + method: 'put', + data: data + }) +} + +// 删除定时任务调度 +export function delJob(jobId) { + return request({ + url: '/monitor/job/' + jobId, + method: 'delete' + }) +} + +// 任务状态修改 +export function changeJobStatus(jobId, status) { + const data = { + jobId, + status + } + return request({ + url: '/monitor/job/changeStatus', + method: 'put', + data: data + }) +} + + +// 定时任务立即执行一次 +export function runJob(jobId, jobGroup) { + const data = { + jobId, + jobGroup + } + return request({ + url: '/monitor/job/run', + method: 'put', + data: data + }) +} \ No newline at end of file diff --git a/zzyl-ui/src/api/monitor/jobLog.js b/zzyl-ui/src/api/monitor/jobLog.js new file mode 100644 index 0000000..6e0be61 --- /dev/null +++ b/zzyl-ui/src/api/monitor/jobLog.js @@ -0,0 +1,26 @@ +import request from '@/utils/request' + +// 查询调度日志列表 +export function listJobLog(query) { + return request({ + url: '/monitor/jobLog/list', + method: 'get', + params: query + }) +} + +// 删除调度日志 +export function delJobLog(jobLogId) { + return request({ + url: '/monitor/jobLog/' + jobLogId, + method: 'delete' + }) +} + +// 清空调度日志 +export function cleanJobLog() { + return request({ + url: '/monitor/jobLog/clean', + method: 'delete' + }) +} diff --git a/zzyl-ui/src/api/monitor/logininfor.js b/zzyl-ui/src/api/monitor/logininfor.js new file mode 100644 index 0000000..4d112b7 --- /dev/null +++ b/zzyl-ui/src/api/monitor/logininfor.js @@ -0,0 +1,34 @@ +import request from '@/utils/request' + +// 查询登录日志列表 +export function list(query) { + return request({ + url: '/monitor/logininfor/list', + method: 'get', + params: query + }) +} + +// 删除登录日志 +export function delLogininfor(infoId) { + return request({ + url: '/monitor/logininfor/' + infoId, + method: 'delete' + }) +} + +// 解锁用户登录状态 +export function unlockLogininfor(userName) { + return request({ + url: '/monitor/logininfor/unlock/' + userName, + method: 'get' + }) +} + +// 清空登录日志 +export function cleanLogininfor() { + return request({ + url: '/monitor/logininfor/clean', + method: 'delete' + }) +} diff --git a/zzyl-ui/src/api/monitor/online.js b/zzyl-ui/src/api/monitor/online.js new file mode 100644 index 0000000..bd22137 --- /dev/null +++ b/zzyl-ui/src/api/monitor/online.js @@ -0,0 +1,18 @@ +import request from '@/utils/request' + +// 查询在线用户列表 +export function list(query) { + return request({ + url: '/monitor/online/list', + method: 'get', + params: query + }) +} + +// 强退用户 +export function forceLogout(tokenId) { + return request({ + url: '/monitor/online/' + tokenId, + method: 'delete' + }) +} diff --git a/zzyl-ui/src/api/monitor/operlog.js b/zzyl-ui/src/api/monitor/operlog.js new file mode 100644 index 0000000..a04bca8 --- /dev/null +++ b/zzyl-ui/src/api/monitor/operlog.js @@ -0,0 +1,26 @@ +import request from '@/utils/request' + +// 查询操作日志列表 +export function list(query) { + return request({ + url: '/monitor/operlog/list', + method: 'get', + params: query + }) +} + +// 删除操作日志 +export function delOperlog(operId) { + return request({ + url: '/monitor/operlog/' + operId, + method: 'delete' + }) +} + +// 清空操作日志 +export function cleanOperlog() { + return request({ + url: '/monitor/operlog/clean', + method: 'delete' + }) +} diff --git a/zzyl-ui/src/api/monitor/server.js b/zzyl-ui/src/api/monitor/server.js new file mode 100644 index 0000000..e1f9ca2 --- /dev/null +++ b/zzyl-ui/src/api/monitor/server.js @@ -0,0 +1,9 @@ +import request from '@/utils/request' + +// 获取服务信息 +export function getServer() { + return request({ + url: '/monitor/server', + method: 'get' + }) +} \ No newline at end of file diff --git a/zzyl-ui/src/api/system/config.js b/zzyl-ui/src/api/system/config.js new file mode 100644 index 0000000..a404d82 --- /dev/null +++ b/zzyl-ui/src/api/system/config.js @@ -0,0 +1,60 @@ +import request from '@/utils/request' + +// 查询参数列表 +export function listConfig(query) { + return request({ + url: '/system/config/list', + method: 'get', + params: query + }) +} + +// 查询参数详细 +export function getConfig(configId) { + return request({ + url: '/system/config/' + configId, + method: 'get' + }) +} + +// 根据参数键名查询参数值 +export function getConfigKey(configKey) { + return request({ + url: '/system/config/configKey/' + configKey, + method: 'get' + }) +} + +// 新增参数配置 +export function addConfig(data) { + return request({ + url: '/system/config', + method: 'post', + data: data + }) +} + +// 修改参数配置 +export function updateConfig(data) { + return request({ + url: '/system/config', + method: 'put', + data: data + }) +} + +// 删除参数配置 +export function delConfig(configId) { + return request({ + url: '/system/config/' + configId, + method: 'delete' + }) +} + +// 刷新参数缓存 +export function refreshCache() { + return request({ + url: '/system/config/refreshCache', + method: 'delete' + }) +} diff --git a/zzyl-ui/src/api/system/dept.js b/zzyl-ui/src/api/system/dept.js new file mode 100644 index 0000000..fc943cd --- /dev/null +++ b/zzyl-ui/src/api/system/dept.js @@ -0,0 +1,52 @@ +import request from '@/utils/request' + +// 查询部门列表 +export function listDept(query) { + return request({ + url: '/system/dept/list', + method: 'get', + params: query + }) +} + +// 查询部门列表(排除节点) +export function listDeptExcludeChild(deptId) { + return request({ + url: '/system/dept/list/exclude/' + deptId, + method: 'get' + }) +} + +// 查询部门详细 +export function getDept(deptId) { + return request({ + url: '/system/dept/' + deptId, + method: 'get' + }) +} + +// 新增部门 +export function addDept(data) { + return request({ + url: '/system/dept', + method: 'post', + data: data + }) +} + +// 修改部门 +export function updateDept(data) { + return request({ + url: '/system/dept', + method: 'put', + data: data + }) +} + +// 删除部门 +export function delDept(deptId) { + return request({ + url: '/system/dept/' + deptId, + method: 'delete' + }) +} \ No newline at end of file diff --git a/zzyl-ui/src/api/system/dict/data.js b/zzyl-ui/src/api/system/dict/data.js new file mode 100644 index 0000000..6c9eb79 --- /dev/null +++ b/zzyl-ui/src/api/system/dict/data.js @@ -0,0 +1,52 @@ +import request from '@/utils/request' + +// 查询字典数据列表 +export function listData(query) { + return request({ + url: '/system/dict/data/list', + method: 'get', + params: query + }) +} + +// 查询字典数据详细 +export function getData(dictCode) { + return request({ + url: '/system/dict/data/' + dictCode, + method: 'get' + }) +} + +// 根据字典类型查询字典数据信息 +export function getDicts(dictType) { + return request({ + url: '/system/dict/data/type/' + dictType, + method: 'get' + }) +} + +// 新增字典数据 +export function addData(data) { + return request({ + url: '/system/dict/data', + method: 'post', + data: data + }) +} + +// 修改字典数据 +export function updateData(data) { + return request({ + url: '/system/dict/data', + method: 'put', + data: data + }) +} + +// 删除字典数据 +export function delData(dictCode) { + return request({ + url: '/system/dict/data/' + dictCode, + method: 'delete' + }) +} diff --git a/zzyl-ui/src/api/system/dict/type.js b/zzyl-ui/src/api/system/dict/type.js new file mode 100644 index 0000000..a7a6e01 --- /dev/null +++ b/zzyl-ui/src/api/system/dict/type.js @@ -0,0 +1,60 @@ +import request from '@/utils/request' + +// 查询字典类型列表 +export function listType(query) { + return request({ + url: '/system/dict/type/list', + method: 'get', + params: query + }) +} + +// 查询字典类型详细 +export function getType(dictId) { + return request({ + url: '/system/dict/type/' + dictId, + method: 'get' + }) +} + +// 新增字典类型 +export function addType(data) { + return request({ + url: '/system/dict/type', + method: 'post', + data: data + }) +} + +// 修改字典类型 +export function updateType(data) { + return request({ + url: '/system/dict/type', + method: 'put', + data: data + }) +} + +// 删除字典类型 +export function delType(dictId) { + return request({ + url: '/system/dict/type/' + dictId, + method: 'delete' + }) +} + +// 刷新字典缓存 +export function refreshCache() { + return request({ + url: '/system/dict/type/refreshCache', + method: 'delete' + }) +} + +// 获取字典选择框列表 +export function optionselect() { + return request({ + url: '/system/dict/type/optionselect', + method: 'get' + }) +} \ No newline at end of file diff --git a/zzyl-ui/src/api/system/menu.js b/zzyl-ui/src/api/system/menu.js new file mode 100644 index 0000000..f6415c6 --- /dev/null +++ b/zzyl-ui/src/api/system/menu.js @@ -0,0 +1,60 @@ +import request from '@/utils/request' + +// 查询菜单列表 +export function listMenu(query) { + return request({ + url: '/system/menu/list', + method: 'get', + params: query + }) +} + +// 查询菜单详细 +export function getMenu(menuId) { + return request({ + url: '/system/menu/' + menuId, + method: 'get' + }) +} + +// 查询菜单下拉树结构 +export function treeselect() { + return request({ + url: '/system/menu/treeselect', + method: 'get' + }) +} + +// 根据角色ID查询菜单下拉树结构 +export function roleMenuTreeselect(roleId) { + return request({ + url: '/system/menu/roleMenuTreeselect/' + roleId, + method: 'get' + }) +} + +// 新增菜单 +export function addMenu(data) { + return request({ + url: '/system/menu', + method: 'post', + data: data + }) +} + +// 修改菜单 +export function updateMenu(data) { + return request({ + url: '/system/menu', + method: 'put', + data: data + }) +} + +// 删除菜单 +export function delMenu(menuId) { + return request({ + url: '/system/menu/' + menuId, + method: 'delete' + }) +} \ No newline at end of file diff --git a/zzyl-ui/src/api/system/notice.js b/zzyl-ui/src/api/system/notice.js new file mode 100644 index 0000000..c274ea5 --- /dev/null +++ b/zzyl-ui/src/api/system/notice.js @@ -0,0 +1,44 @@ +import request from '@/utils/request' + +// 查询公告列表 +export function listNotice(query) { + return request({ + url: '/system/notice/list', + method: 'get', + params: query + }) +} + +// 查询公告详细 +export function getNotice(noticeId) { + return request({ + url: '/system/notice/' + noticeId, + method: 'get' + }) +} + +// 新增公告 +export function addNotice(data) { + return request({ + url: '/system/notice', + method: 'post', + data: data + }) +} + +// 修改公告 +export function updateNotice(data) { + return request({ + url: '/system/notice', + method: 'put', + data: data + }) +} + +// 删除公告 +export function delNotice(noticeId) { + return request({ + url: '/system/notice/' + noticeId, + method: 'delete' + }) +} \ No newline at end of file diff --git a/zzyl-ui/src/api/system/post.js b/zzyl-ui/src/api/system/post.js new file mode 100644 index 0000000..1a8e9ca --- /dev/null +++ b/zzyl-ui/src/api/system/post.js @@ -0,0 +1,44 @@ +import request from '@/utils/request' + +// 查询岗位列表 +export function listPost(query) { + return request({ + url: '/system/post/list', + method: 'get', + params: query + }) +} + +// 查询岗位详细 +export function getPost(postId) { + return request({ + url: '/system/post/' + postId, + method: 'get' + }) +} + +// 新增岗位 +export function addPost(data) { + return request({ + url: '/system/post', + method: 'post', + data: data + }) +} + +// 修改岗位 +export function updatePost(data) { + return request({ + url: '/system/post', + method: 'put', + data: data + }) +} + +// 删除岗位 +export function delPost(postId) { + return request({ + url: '/system/post/' + postId, + method: 'delete' + }) +} diff --git a/zzyl-ui/src/api/system/role.js b/zzyl-ui/src/api/system/role.js new file mode 100644 index 0000000..f13e6f4 --- /dev/null +++ b/zzyl-ui/src/api/system/role.js @@ -0,0 +1,119 @@ +import request from '@/utils/request' + +// 查询角色列表 +export function listRole(query) { + return request({ + url: '/system/role/list', + method: 'get', + params: query + }) +} + +// 查询角色详细 +export function getRole(roleId) { + return request({ + url: '/system/role/' + roleId, + method: 'get' + }) +} + +// 新增角色 +export function addRole(data) { + return request({ + url: '/system/role', + method: 'post', + data: data + }) +} + +// 修改角色 +export function updateRole(data) { + return request({ + url: '/system/role', + method: 'put', + data: data + }) +} + +// 角色数据权限 +export function dataScope(data) { + return request({ + url: '/system/role/dataScope', + method: 'put', + data: data + }) +} + +// 角色状态修改 +export function changeRoleStatus(roleId, status) { + const data = { + roleId, + status + } + return request({ + url: '/system/role/changeStatus', + method: 'put', + data: data + }) +} + +// 删除角色 +export function delRole(roleId) { + return request({ + url: '/system/role/' + roleId, + method: 'delete' + }) +} + +// 查询角色已授权用户列表 +export function allocatedUserList(query) { + return request({ + url: '/system/role/authUser/allocatedList', + method: 'get', + params: query + }) +} + +// 查询角色未授权用户列表 +export function unallocatedUserList(query) { + return request({ + url: '/system/role/authUser/unallocatedList', + method: 'get', + params: query + }) +} + +// 取消用户授权角色 +export function authUserCancel(data) { + return request({ + url: '/system/role/authUser/cancel', + method: 'put', + data: data + }) +} + +// 批量取消用户授权角色 +export function authUserCancelAll(data) { + return request({ + url: '/system/role/authUser/cancelAll', + method: 'put', + params: data + }) +} + +// 授权用户选择 +export function authUserSelectAll(data) { + return request({ + url: '/system/role/authUser/selectAll', + method: 'put', + params: data + }) +} + +// 根据角色ID查询部门树结构 +export function deptTreeSelect(roleId) { + return request({ + url: '/system/role/deptTree/' + roleId, + method: 'get' + }) +} diff --git a/zzyl-ui/src/api/system/user.js b/zzyl-ui/src/api/system/user.js new file mode 100644 index 0000000..9b0211a --- /dev/null +++ b/zzyl-ui/src/api/system/user.js @@ -0,0 +1,136 @@ +import request from '@/utils/request' +import { parseStrEmpty } from "@/utils/ruoyi"; + +// 查询用户列表 +export function listUser(query) { + return request({ + url: '/system/user/list', + method: 'get', + params: query + }) +} + +// 查询用户详细 +export function getUser(userId) { + return request({ + url: '/system/user/' + parseStrEmpty(userId), + method: 'get' + }) +} + +// 新增用户 +export function addUser(data) { + return request({ + url: '/system/user', + method: 'post', + data: data + }) +} + +// 修改用户 +export function updateUser(data) { + return request({ + url: '/system/user', + method: 'put', + data: data + }) +} + +// 删除用户 +export function delUser(userId) { + return request({ + url: '/system/user/' + userId, + method: 'delete' + }) +} + +// 用户密码重置 +export function resetUserPwd(userId, password) { + const data = { + userId, + password + } + return request({ + url: '/system/user/resetPwd', + method: 'put', + data: data + }) +} + +// 用户状态修改 +export function changeUserStatus(userId, status) { + const data = { + userId, + status + } + return request({ + url: '/system/user/changeStatus', + method: 'put', + data: data + }) +} + +// 查询用户个人信息 +export function getUserProfile() { + return request({ + url: '/system/user/profile', + method: 'get' + }) +} + +// 修改用户个人信息 +export function updateUserProfile(data) { + return request({ + url: '/system/user/profile', + method: 'put', + data: data + }) +} + +// 用户密码重置 +export function updateUserPwd(oldPassword, newPassword) { + const data = { + oldPassword, + newPassword + } + return request({ + url: '/system/user/profile/updatePwd', + method: 'put', + params: data + }) +} + +// 用户头像上传 +export function uploadAvatar(data) { + return request({ + url: '/system/user/profile/avatar', + method: 'post', + headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, + data: data + }) +} + +// 查询授权角色 +export function getAuthRole(userId) { + return request({ + url: '/system/user/authRole/' + userId, + method: 'get' + }) +} + +// 保存授权角色 +export function updateAuthRole(data) { + return request({ + url: '/system/user/authRole', + method: 'put', + params: data + }) +} + +// 查询部门下拉树结构 +export function deptTreeSelect() { + return request({ + url: '/system/user/deptTree', + method: 'get' + }) +} diff --git a/zzyl-ui/src/api/tool/gen.js b/zzyl-ui/src/api/tool/gen.js new file mode 100644 index 0000000..2075677 --- /dev/null +++ b/zzyl-ui/src/api/tool/gen.js @@ -0,0 +1,85 @@ +import request from '@/utils/request' + +// 查询生成表数据 +export function listTable(query) { + return request({ + url: '/tool/gen/list', + method: 'get', + params: query + }) +} +// 查询db数据库列表 +export function listDbTable(query) { + return request({ + url: '/tool/gen/db/list', + method: 'get', + params: query + }) +} + +// 查询表详细信息 +export function getGenTable(tableId) { + return request({ + url: '/tool/gen/' + tableId, + method: 'get' + }) +} + +// 修改代码生成信息 +export function updateGenTable(data) { + return request({ + url: '/tool/gen', + method: 'put', + data: data + }) +} + +// 导入表 +export function importTable(data) { + return request({ + url: '/tool/gen/importTable', + method: 'post', + params: data + }) +} + +// 创建表 +export function createTable(data) { + return request({ + url: '/tool/gen/createTable', + method: 'post', + params: data + }) +} + +// 预览生成代码 +export function previewTable(tableId) { + return request({ + url: '/tool/gen/preview/' + tableId, + method: 'get' + }) +} + +// 删除表数据 +export function delTable(tableId) { + return request({ + url: '/tool/gen/' + tableId, + method: 'delete' + }) +} + +// 生成代码(自定义路径) +export function genCode(tableName) { + return request({ + url: '/tool/gen/genCode/' + tableName, + method: 'get' + }) +} + +// 同步数据库 +export function synchDb(tableName) { + return request({ + url: '/tool/gen/synchDb/' + tableName, + method: 'get' + }) +} diff --git a/zzyl-ui/src/assets/401_images/401.gif b/zzyl-ui/src/assets/401_images/401.gif new file mode 100644 index 0000000..cd6e0d9 Binary files /dev/null and b/zzyl-ui/src/assets/401_images/401.gif differ diff --git a/zzyl-ui/src/assets/404_images/404.png b/zzyl-ui/src/assets/404_images/404.png new file mode 100644 index 0000000..3d8e230 Binary files /dev/null and b/zzyl-ui/src/assets/404_images/404.png differ diff --git a/zzyl-ui/src/assets/404_images/404_cloud.png b/zzyl-ui/src/assets/404_images/404_cloud.png new file mode 100644 index 0000000..c6281d0 Binary files /dev/null and b/zzyl-ui/src/assets/404_images/404_cloud.png differ diff --git a/zzyl-ui/src/assets/icons/index.js b/zzyl-ui/src/assets/icons/index.js new file mode 100644 index 0000000..2c6b309 --- /dev/null +++ b/zzyl-ui/src/assets/icons/index.js @@ -0,0 +1,9 @@ +import Vue from 'vue' +import SvgIcon from '@/components/SvgIcon'// svg component + +// register globally +Vue.component('svg-icon', SvgIcon) + +const req = require.context('./svg', false, /\.svg$/) +const requireAll = requireContext => requireContext.keys().map(requireContext) +requireAll(req) diff --git a/zzyl-ui/src/assets/icons/svg/404.svg b/zzyl-ui/src/assets/icons/svg/404.svg new file mode 100644 index 0000000..6df5019 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/404.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/bug.svg b/zzyl-ui/src/assets/icons/svg/bug.svg new file mode 100644 index 0000000..05a150d --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/bug.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/build.svg b/zzyl-ui/src/assets/icons/svg/build.svg new file mode 100644 index 0000000..97c4688 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/build.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/button.svg b/zzyl-ui/src/assets/icons/svg/button.svg new file mode 100644 index 0000000..904fddc --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/button.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/cascader.svg b/zzyl-ui/src/assets/icons/svg/cascader.svg new file mode 100644 index 0000000..e256024 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/cascader.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/chart.svg b/zzyl-ui/src/assets/icons/svg/chart.svg new file mode 100644 index 0000000..27728fb --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/chart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/checkbox.svg b/zzyl-ui/src/assets/icons/svg/checkbox.svg new file mode 100644 index 0000000..013fd3a --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/checkbox.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/clipboard.svg b/zzyl-ui/src/assets/icons/svg/clipboard.svg new file mode 100644 index 0000000..90923ff --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/clipboard.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/code.svg b/zzyl-ui/src/assets/icons/svg/code.svg new file mode 100644 index 0000000..5f9c5ab --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/code.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/color.svg b/zzyl-ui/src/assets/icons/svg/color.svg new file mode 100644 index 0000000..44a81aa --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/color.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/component.svg b/zzyl-ui/src/assets/icons/svg/component.svg new file mode 100644 index 0000000..29c3458 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/component.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/dashboard.svg b/zzyl-ui/src/assets/icons/svg/dashboard.svg new file mode 100644 index 0000000..5317d37 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/dashboard.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/date-range.svg b/zzyl-ui/src/assets/icons/svg/date-range.svg new file mode 100644 index 0000000..fda571e --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/date-range.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/date.svg b/zzyl-ui/src/assets/icons/svg/date.svg new file mode 100644 index 0000000..52dc73e --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/date.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/dict.svg b/zzyl-ui/src/assets/icons/svg/dict.svg new file mode 100644 index 0000000..4849377 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/dict.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/documentation.svg b/zzyl-ui/src/assets/icons/svg/documentation.svg new file mode 100644 index 0000000..7043122 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/documentation.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/download.svg b/zzyl-ui/src/assets/icons/svg/download.svg new file mode 100644 index 0000000..c896951 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/download.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/drag.svg b/zzyl-ui/src/assets/icons/svg/drag.svg new file mode 100644 index 0000000..4185d3c --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/drag.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/druid.svg b/zzyl-ui/src/assets/icons/svg/druid.svg new file mode 100644 index 0000000..a2b4b4e --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/druid.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/edit.svg b/zzyl-ui/src/assets/icons/svg/edit.svg new file mode 100644 index 0000000..d26101f --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/edit.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/education.svg b/zzyl-ui/src/assets/icons/svg/education.svg new file mode 100644 index 0000000..7bfb01d --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/education.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/email.svg b/zzyl-ui/src/assets/icons/svg/email.svg new file mode 100644 index 0000000..74d25e2 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/email.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/example.svg b/zzyl-ui/src/assets/icons/svg/example.svg new file mode 100644 index 0000000..46f42b5 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/example.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/excel.svg b/zzyl-ui/src/assets/icons/svg/excel.svg new file mode 100644 index 0000000..74d97b8 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/excel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/exit-fullscreen.svg b/zzyl-ui/src/assets/icons/svg/exit-fullscreen.svg new file mode 100644 index 0000000..485c128 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/exit-fullscreen.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/eye-open.svg b/zzyl-ui/src/assets/icons/svg/eye-open.svg new file mode 100644 index 0000000..88dcc98 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/eye-open.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/eye.svg b/zzyl-ui/src/assets/icons/svg/eye.svg new file mode 100644 index 0000000..16ed2d8 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/eye.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/form.svg b/zzyl-ui/src/assets/icons/svg/form.svg new file mode 100644 index 0000000..dcbaa18 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/form.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/fullscreen.svg b/zzyl-ui/src/assets/icons/svg/fullscreen.svg new file mode 100644 index 0000000..0e86b6f --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/fullscreen.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/github.svg b/zzyl-ui/src/assets/icons/svg/github.svg new file mode 100644 index 0000000..db0a0d4 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/github.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/guide.svg b/zzyl-ui/src/assets/icons/svg/guide.svg new file mode 100644 index 0000000..b271001 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/guide.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/icon.svg b/zzyl-ui/src/assets/icons/svg/icon.svg new file mode 100644 index 0000000..82be8ee --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/input.svg b/zzyl-ui/src/assets/icons/svg/input.svg new file mode 100644 index 0000000..ab91381 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/input.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/international.svg b/zzyl-ui/src/assets/icons/svg/international.svg new file mode 100644 index 0000000..e9b56ee --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/international.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/job.svg b/zzyl-ui/src/assets/icons/svg/job.svg new file mode 100644 index 0000000..2a93a25 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/job.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/language.svg b/zzyl-ui/src/assets/icons/svg/language.svg new file mode 100644 index 0000000..0082b57 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/language.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/link.svg b/zzyl-ui/src/assets/icons/svg/link.svg new file mode 100644 index 0000000..48197ba --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/link.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/list.svg b/zzyl-ui/src/assets/icons/svg/list.svg new file mode 100644 index 0000000..20259ed --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/list.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/lock.svg b/zzyl-ui/src/assets/icons/svg/lock.svg new file mode 100644 index 0000000..74fee54 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/lock.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/log.svg b/zzyl-ui/src/assets/icons/svg/log.svg new file mode 100644 index 0000000..d879d33 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/log.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/logininfor.svg b/zzyl-ui/src/assets/icons/svg/logininfor.svg new file mode 100644 index 0000000..267f844 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/logininfor.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/message.svg b/zzyl-ui/src/assets/icons/svg/message.svg new file mode 100644 index 0000000..14ca817 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/message.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/money.svg b/zzyl-ui/src/assets/icons/svg/money.svg new file mode 100644 index 0000000..c1580de --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/money.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/monitor.svg b/zzyl-ui/src/assets/icons/svg/monitor.svg new file mode 100644 index 0000000..bc308cb --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/monitor.svg @@ -0,0 +1,2 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/nested.svg b/zzyl-ui/src/assets/icons/svg/nested.svg new file mode 100644 index 0000000..06713a8 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/nested.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/number.svg b/zzyl-ui/src/assets/icons/svg/number.svg new file mode 100644 index 0000000..ad5ce9a --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/number.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/online.svg b/zzyl-ui/src/assets/icons/svg/online.svg new file mode 100644 index 0000000..330a202 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/online.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/password.svg b/zzyl-ui/src/assets/icons/svg/password.svg new file mode 100644 index 0000000..6c64def --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/password.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/pdf.svg b/zzyl-ui/src/assets/icons/svg/pdf.svg new file mode 100644 index 0000000..957aa0c --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/pdf.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/people.svg b/zzyl-ui/src/assets/icons/svg/people.svg new file mode 100644 index 0000000..2bd54ae --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/people.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/peoples.svg b/zzyl-ui/src/assets/icons/svg/peoples.svg new file mode 100644 index 0000000..aab852e --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/peoples.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/phone.svg b/zzyl-ui/src/assets/icons/svg/phone.svg new file mode 100644 index 0000000..ab8e8c4 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/phone.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/post.svg b/zzyl-ui/src/assets/icons/svg/post.svg new file mode 100644 index 0000000..2922c61 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/post.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/qq.svg b/zzyl-ui/src/assets/icons/svg/qq.svg new file mode 100644 index 0000000..ee13d4e --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/qq.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/question.svg b/zzyl-ui/src/assets/icons/svg/question.svg new file mode 100644 index 0000000..cf75bd4 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/question.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/radio.svg b/zzyl-ui/src/assets/icons/svg/radio.svg new file mode 100644 index 0000000..0cde345 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/radio.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/rate.svg b/zzyl-ui/src/assets/icons/svg/rate.svg new file mode 100644 index 0000000..aa3b14d --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/rate.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/redis-list.svg b/zzyl-ui/src/assets/icons/svg/redis-list.svg new file mode 100644 index 0000000..98a15b2 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/redis-list.svg @@ -0,0 +1,2 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/redis.svg b/zzyl-ui/src/assets/icons/svg/redis.svg new file mode 100644 index 0000000..2f1d62d --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/redis.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/row.svg b/zzyl-ui/src/assets/icons/svg/row.svg new file mode 100644 index 0000000..0780992 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/row.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/search.svg b/zzyl-ui/src/assets/icons/svg/search.svg new file mode 100644 index 0000000..84233dd --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/search.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/select.svg b/zzyl-ui/src/assets/icons/svg/select.svg new file mode 100644 index 0000000..d628382 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/select.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/server.svg b/zzyl-ui/src/assets/icons/svg/server.svg new file mode 100644 index 0000000..eb287e3 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/server.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/shopping.svg b/zzyl-ui/src/assets/icons/svg/shopping.svg new file mode 100644 index 0000000..87513e7 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/shopping.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/size.svg b/zzyl-ui/src/assets/icons/svg/size.svg new file mode 100644 index 0000000..ddb25b8 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/size.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/skill.svg b/zzyl-ui/src/assets/icons/svg/skill.svg new file mode 100644 index 0000000..a3b7312 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/skill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/slider.svg b/zzyl-ui/src/assets/icons/svg/slider.svg new file mode 100644 index 0000000..fbe4f39 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/slider.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/star.svg b/zzyl-ui/src/assets/icons/svg/star.svg new file mode 100644 index 0000000..6cf86e6 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/star.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/swagger.svg b/zzyl-ui/src/assets/icons/svg/swagger.svg new file mode 100644 index 0000000..05d4e7b --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/swagger.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/switch.svg b/zzyl-ui/src/assets/icons/svg/switch.svg new file mode 100644 index 0000000..0ba61e3 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/switch.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/system.svg b/zzyl-ui/src/assets/icons/svg/system.svg new file mode 100644 index 0000000..5992593 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/system.svg @@ -0,0 +1,2 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/tab.svg b/zzyl-ui/src/assets/icons/svg/tab.svg new file mode 100644 index 0000000..b4b48e4 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/tab.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/table.svg b/zzyl-ui/src/assets/icons/svg/table.svg new file mode 100644 index 0000000..0e3dc9d --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/table.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/textarea.svg b/zzyl-ui/src/assets/icons/svg/textarea.svg new file mode 100644 index 0000000..2709f29 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/textarea.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/theme.svg b/zzyl-ui/src/assets/icons/svg/theme.svg new file mode 100644 index 0000000..5982a2f --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/theme.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/time-range.svg b/zzyl-ui/src/assets/icons/svg/time-range.svg new file mode 100644 index 0000000..13c1202 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/time-range.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/time.svg b/zzyl-ui/src/assets/icons/svg/time.svg new file mode 100644 index 0000000..b376e32 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/time.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/tool.svg b/zzyl-ui/src/assets/icons/svg/tool.svg new file mode 100644 index 0000000..48e0e35 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/tool.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/tree-table.svg b/zzyl-ui/src/assets/icons/svg/tree-table.svg new file mode 100644 index 0000000..8aafdb8 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/tree-table.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/tree.svg b/zzyl-ui/src/assets/icons/svg/tree.svg new file mode 100644 index 0000000..dd4b7dd --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/tree.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/upload.svg b/zzyl-ui/src/assets/icons/svg/upload.svg new file mode 100644 index 0000000..bae49c0 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/upload.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/user.svg b/zzyl-ui/src/assets/icons/svg/user.svg new file mode 100644 index 0000000..0ba0716 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/user.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/validCode.svg b/zzyl-ui/src/assets/icons/svg/validCode.svg new file mode 100644 index 0000000..cfb1021 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/validCode.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/wechat.svg b/zzyl-ui/src/assets/icons/svg/wechat.svg new file mode 100644 index 0000000..c586e55 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/wechat.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svg/zip.svg b/zzyl-ui/src/assets/icons/svg/zip.svg new file mode 100644 index 0000000..f806fc4 --- /dev/null +++ b/zzyl-ui/src/assets/icons/svg/zip.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zzyl-ui/src/assets/icons/svgo.yml b/zzyl-ui/src/assets/icons/svgo.yml new file mode 100644 index 0000000..d11906a --- /dev/null +++ b/zzyl-ui/src/assets/icons/svgo.yml @@ -0,0 +1,22 @@ +# replace default config + +# multipass: true +# full: true + +plugins: + + # - name + # + # or: + # - name: false + # - name: true + # + # or: + # - name: + # param1: 1 + # param2: 2 + +- removeAttrs: + attrs: + - 'fill' + - 'fill-rule' diff --git a/zzyl-ui/src/assets/images/dark.svg b/zzyl-ui/src/assets/images/dark.svg new file mode 100644 index 0000000..f646bd7 --- /dev/null +++ b/zzyl-ui/src/assets/images/dark.svg @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/zzyl-ui/src/assets/images/light.svg b/zzyl-ui/src/assets/images/light.svg new file mode 100644 index 0000000..ab7cc08 --- /dev/null +++ b/zzyl-ui/src/assets/images/light.svg @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/zzyl-ui/src/assets/images/login-background.jpg b/zzyl-ui/src/assets/images/login-background.jpg new file mode 100644 index 0000000..8a89eb8 Binary files /dev/null and b/zzyl-ui/src/assets/images/login-background.jpg differ diff --git a/zzyl-ui/src/assets/images/pay.png b/zzyl-ui/src/assets/images/pay.png new file mode 100644 index 0000000..bb8b967 Binary files /dev/null and b/zzyl-ui/src/assets/images/pay.png differ diff --git a/zzyl-ui/src/assets/images/profile.jpg b/zzyl-ui/src/assets/images/profile.jpg new file mode 100644 index 0000000..b3a940b Binary files /dev/null and b/zzyl-ui/src/assets/images/profile.jpg differ diff --git a/zzyl-ui/src/assets/logo/logo.png b/zzyl-ui/src/assets/logo/logo.png new file mode 100644 index 0000000..e263760 Binary files /dev/null and b/zzyl-ui/src/assets/logo/logo.png differ diff --git a/zzyl-ui/src/assets/styles/btn.scss b/zzyl-ui/src/assets/styles/btn.scss new file mode 100644 index 0000000..e6ba1a8 --- /dev/null +++ b/zzyl-ui/src/assets/styles/btn.scss @@ -0,0 +1,99 @@ +@import './variables.scss'; + +@mixin colorBtn($color) { + background: $color; + + &:hover { + color: $color; + + &:before, + &:after { + background: $color; + } + } +} + +.blue-btn { + @include colorBtn($blue) +} + +.light-blue-btn { + @include colorBtn($light-blue) +} + +.red-btn { + @include colorBtn($red) +} + +.pink-btn { + @include colorBtn($pink) +} + +.green-btn { + @include colorBtn($green) +} + +.tiffany-btn { + @include colorBtn($tiffany) +} + +.yellow-btn { + @include colorBtn($yellow) +} + +.pan-btn { + font-size: 14px; + color: #fff; + padding: 14px 36px; + border-radius: 8px; + border: none; + outline: none; + transition: 600ms ease all; + position: relative; + display: inline-block; + + &:hover { + background: #fff; + + &:before, + &:after { + width: 100%; + transition: 600ms ease all; + } + } + + &:before, + &:after { + content: ''; + position: absolute; + top: 0; + right: 0; + height: 2px; + width: 0; + transition: 400ms ease all; + } + + &::after { + right: inherit; + top: inherit; + left: 0; + bottom: 0; + } +} + +.custom-button { + display: inline-block; + line-height: 1; + white-space: nowrap; + cursor: pointer; + background: #fff; + color: #fff; + -webkit-appearance: none; + text-align: center; + box-sizing: border-box; + outline: 0; + margin: 0; + padding: 10px 15px; + font-size: 14px; + border-radius: 4px; +} diff --git a/zzyl-ui/src/assets/styles/element-ui.scss b/zzyl-ui/src/assets/styles/element-ui.scss new file mode 100644 index 0000000..363092a --- /dev/null +++ b/zzyl-ui/src/assets/styles/element-ui.scss @@ -0,0 +1,92 @@ +// cover some element-ui styles + +.el-breadcrumb__inner, +.el-breadcrumb__inner a { + font-weight: 400 !important; +} + +.el-upload { + input[type="file"] { + display: none !important; + } +} + +.el-upload__input { + display: none; +} + +.cell { + .el-tag { + margin-right: 0px; + } +} + +.small-padding { + .cell { + padding-left: 5px; + padding-right: 5px; + } +} + +.fixed-width { + .el-button--mini { + padding: 7px 10px; + width: 60px; + } +} + +.status-col { + .cell { + padding: 0 10px; + text-align: center; + + .el-tag { + margin-right: 0px; + } + } +} + +// to fixed https://github.com/ElemeFE/element/issues/2461 +.el-dialog { + transform: none; + left: 0; + position: relative; + margin: 0 auto; +} + +// refine element ui upload +.upload-container { + .el-upload { + width: 100%; + + .el-upload-dragger { + width: 100%; + height: 200px; + } + } +} + +// dropdown +.el-dropdown-menu { + a { + display: block + } +} + +// fix date-picker ui bug in filter-item +.el-range-editor.el-input__inner { + display: inline-flex !important; +} + +// to fix el-date-picker css style +.el-range-separator { + box-sizing: content-box; +} + +.el-menu--collapse + > div + > .el-submenu + > .el-submenu__title + .el-submenu__icon-arrow { + display: none; +} \ No newline at end of file diff --git a/zzyl-ui/src/assets/styles/element-variables.scss b/zzyl-ui/src/assets/styles/element-variables.scss new file mode 100644 index 0000000..1615ff2 --- /dev/null +++ b/zzyl-ui/src/assets/styles/element-variables.scss @@ -0,0 +1,31 @@ +/** +* I think element-ui's default theme color is too light for long-term use. +* So I modified the default color and you can modify it to your liking. +**/ + +/* theme color */ +$--color-primary: #1890ff; +$--color-success: #13ce66; +$--color-warning: #ffba00; +$--color-danger: #ff4949; +// $--color-info: #1E1E1E; + +$--button-font-weight: 400; + +// $--color-text-regular: #1f2d3d; + +$--border-color-light: #dfe4ed; +$--border-color-lighter: #e6ebf5; + +$--table-border: 1px solid #dfe6ec; + +/* icon font path, required */ +$--font-path: '~element-ui/lib/theme-chalk/fonts'; + +@import "~element-ui/packages/theme-chalk/src/index"; + +// the :export directive is the magic sauce for webpack +// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass +:export { + theme: $--color-primary; +} diff --git a/zzyl-ui/src/assets/styles/index.scss b/zzyl-ui/src/assets/styles/index.scss new file mode 100644 index 0000000..2f3b9ef --- /dev/null +++ b/zzyl-ui/src/assets/styles/index.scss @@ -0,0 +1,182 @@ +@import './variables.scss'; +@import './mixin.scss'; +@import './transition.scss'; +@import './element-ui.scss'; +@import './sidebar.scss'; +@import './btn.scss'; + +body { + height: 100%; + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + text-rendering: optimizeLegibility; + font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif; +} + +label { + font-weight: 700; +} + +html { + height: 100%; + box-sizing: border-box; +} + +#app { + height: 100%; +} + +*, +*:before, +*:after { + box-sizing: inherit; +} + +.no-padding { + padding: 0px !important; +} + +.padding-content { + padding: 4px 0; +} + +a:focus, +a:active { + outline: none; +} + +a, +a:focus, +a:hover { + cursor: pointer; + color: inherit; + text-decoration: none; +} + +div:focus { + outline: none; +} + +.fr { + float: right; +} + +.fl { + float: left; +} + +.pr-5 { + padding-right: 5px; +} + +.pl-5 { + padding-left: 5px; +} + +.block { + display: block; +} + +.pointer { + cursor: pointer; +} + +.inlineBlock { + display: block; +} + +.clearfix { + &:after { + visibility: hidden; + display: block; + font-size: 0; + content: " "; + clear: both; + height: 0; + } +} + +aside { + background: #eef1f6; + padding: 8px 24px; + margin-bottom: 20px; + border-radius: 2px; + display: block; + line-height: 32px; + font-size: 16px; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; + color: #2c3e50; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + + a { + color: #337ab7; + cursor: pointer; + + &:hover { + color: rgb(32, 160, 255); + } + } +} + +//main-container全局样式 +.app-container { + padding: 20px; +} + +.components-container { + margin: 30px 50px; + position: relative; +} + +.pagination-container { + margin-top: 30px; +} + +.text-center { + text-align: center +} + +.sub-navbar { + height: 50px; + line-height: 50px; + position: relative; + width: 100%; + text-align: right; + padding-right: 20px; + transition: 600ms ease position; + background: linear-gradient(90deg, rgba(32, 182, 249, 1) 0%, rgba(32, 182, 249, 1) 0%, rgba(33, 120, 241, 1) 100%, rgba(33, 120, 241, 1) 100%); + + .subtitle { + font-size: 20px; + color: #fff; + } + + &.draft { + background: #d0d0d0; + } + + &.deleted { + background: #d0d0d0; + } +} + +.link-type, +.link-type:focus { + color: #337ab7; + cursor: pointer; + + &:hover { + color: rgb(32, 160, 255); + } +} + +.filter-container { + padding-bottom: 10px; + + .filter-item { + display: inline-block; + vertical-align: middle; + margin-bottom: 10px; + } +} diff --git a/zzyl-ui/src/assets/styles/mixin.scss b/zzyl-ui/src/assets/styles/mixin.scss new file mode 100644 index 0000000..06fa061 --- /dev/null +++ b/zzyl-ui/src/assets/styles/mixin.scss @@ -0,0 +1,66 @@ +@mixin clearfix { + &:after { + content: ""; + display: table; + clear: both; + } +} + +@mixin scrollBar { + &::-webkit-scrollbar-track-piece { + background: #d3dce6; + } + + &::-webkit-scrollbar { + width: 6px; + } + + &::-webkit-scrollbar-thumb { + background: #99a9bf; + border-radius: 20px; + } +} + +@mixin relative { + position: relative; + width: 100%; + height: 100%; +} + +@mixin pct($pct) { + width: #{$pct}; + position: relative; + margin: 0 auto; +} + +@mixin triangle($width, $height, $color, $direction) { + $width: $width/2; + $color-border-style: $height solid $color; + $transparent-border-style: $width solid transparent; + height: 0; + width: 0; + + @if $direction==up { + border-bottom: $color-border-style; + border-left: $transparent-border-style; + border-right: $transparent-border-style; + } + + @else if $direction==right { + border-left: $color-border-style; + border-top: $transparent-border-style; + border-bottom: $transparent-border-style; + } + + @else if $direction==down { + border-top: $color-border-style; + border-left: $transparent-border-style; + border-right: $transparent-border-style; + } + + @else if $direction==left { + border-right: $color-border-style; + border-top: $transparent-border-style; + border-bottom: $transparent-border-style; + } +} diff --git a/zzyl-ui/src/assets/styles/ruoyi.scss b/zzyl-ui/src/assets/styles/ruoyi.scss new file mode 100644 index 0000000..4e29874 --- /dev/null +++ b/zzyl-ui/src/assets/styles/ruoyi.scss @@ -0,0 +1,291 @@ +/** +* 通用css样式布局处理 +* Copyright (c) 2019 ruoyi +*/ + +/** 基础通用 **/ +.pt5 { + padding-top: 5px; +} + +.pr5 { + padding-right: 5px; +} + +.pb5 { + padding-bottom: 5px; +} + +.mt5 { + margin-top: 5px; +} + +.mr5 { + margin-right: 5px; +} + +.mb5 { + margin-bottom: 5px; +} + +.mb8 { + margin-bottom: 8px; +} + +.ml5 { + margin-left: 5px; +} + +.mt10 { + margin-top: 10px; +} + +.mr10 { + margin-right: 10px; +} + +.mb10 { + margin-bottom: 10px; +} +.ml10 { + margin-left: 10px; +} + +.mt20 { + margin-top: 20px; +} + +.mr20 { + margin-right: 20px; +} + +.mb20 { + margin-bottom: 20px; +} +.ml20 { + margin-left: 20px; +} + +.h1, .h2, .h3, .h4, .h5, .h6, h1, h2, h3, h4, h5, h6 { + font-family: inherit; + font-weight: 500; + line-height: 1.1; + color: inherit; +} + +.el-message-box__status + .el-message-box__message{ + word-break: break-word; +} + +.el-dialog:not(.is-fullscreen) { + margin-top: 6vh !important; +} + +.el-dialog__wrapper.scrollbar .el-dialog .el-dialog__body { + overflow: auto; + overflow-x: hidden; + max-height: 70vh; + padding: 10px 20px 0; +} + +.el-table { + .el-table__header-wrapper, .el-table__fixed-header-wrapper { + th { + word-break: break-word; + background-color: #f8f8f9; + color: #515a6e; + height: 40px; + font-size: 13px; + } + } + + .el-table__body-wrapper { + .el-button [class*="el-icon-"] + span { + margin-left: 1px; + } + } +} + +/** 表单布局 **/ +.form-header { + font-size: 15px; + color: #6379bb; + border-bottom: 1px solid #ddd; + margin: 8px 10px 25px 10px; + padding-bottom: 5px +} + +/** 表格布局 **/ +.pagination-container { + position: relative; + height: 25px; + margin-bottom: 10px; + margin-top: 15px; + padding: 10px 20px !important; +} + +/* tree border */ +.tree-border { + margin-top: 5px; + border: 1px solid #e5e6e7; + background: #FFFFFF none; + border-radius: 4px; +} + +.pagination-container .el-pagination { + right: 0; + position: absolute; +} + +@media (max-width: 768px) { + .pagination-container .el-pagination > .el-pagination__jump { + display: none !important; + } + .pagination-container .el-pagination > .el-pagination__sizes { + display: none !important; + } +} + +.el-table .fixed-width .el-button--mini { + padding-left: 0; + padding-right: 0; + width: inherit; +} + +/** 表格更多操作下拉样式 */ +.el-table .el-dropdown-link,.el-table .el-dropdown-selfdefine { + cursor: pointer; + margin-left: 5px; +} + +.el-table .el-dropdown, .el-icon-arrow-down { + font-size: 12px; +} + +.el-tree-node__content > .el-checkbox { + margin-right: 8px; +} + +.list-group-striped > .list-group-item { + border-left: 0; + border-right: 0; + border-radius: 0; + padding-left: 0; + padding-right: 0; +} + +.list-group { + padding-left: 0px; + list-style: none; +} + +.list-group-item { + border-bottom: 1px solid #e7eaec; + border-top: 1px solid #e7eaec; + margin-bottom: -1px; + padding: 11px 0px; + font-size: 13px; +} + +.pull-right { + float: right !important; +} + +.el-card__header { + padding: 14px 15px 7px; + min-height: 40px; +} + +.el-card__body { + padding: 15px 20px 20px 20px; +} + +.card-box { + padding-right: 15px; + padding-left: 15px; + margin-bottom: 10px; +} + +/* button color */ +.el-button--cyan.is-active, +.el-button--cyan:active { + background: #20B2AA; + border-color: #20B2AA; + color: #FFFFFF; +} + +.el-button--cyan:focus, +.el-button--cyan:hover { + background: #48D1CC; + border-color: #48D1CC; + color: #FFFFFF; +} + +.el-button--cyan { + background-color: #20B2AA; + border-color: #20B2AA; + color: #FFFFFF; +} + +/* text color */ +.text-navy { + color: #1ab394; +} + +.text-primary { + color: inherit; +} + +.text-success { + color: #1c84c6; +} + +.text-info { + color: #23c6c8; +} + +.text-warning { + color: #f8ac59; +} + +.text-danger { + color: #ed5565; +} + +.text-muted { + color: #888888; +} + +/* image */ +.img-circle { + border-radius: 50%; +} + +.img-lg { + width: 120px; + height: 120px; +} + +.avatar-upload-preview { + position: relative; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 200px; + height: 200px; + border-radius: 50%; + box-shadow: 0 0 4px #ccc; + overflow: hidden; +} + +/* 拖拽列样式 */ +.sortable-ghost { + opacity: .8; + color: #fff !important; + background: #42b983 !important; +} + +.top-right-btn { + position: relative; + float: right; +} diff --git a/zzyl-ui/src/assets/styles/sidebar.scss b/zzyl-ui/src/assets/styles/sidebar.scss new file mode 100644 index 0000000..abe5b63 --- /dev/null +++ b/zzyl-ui/src/assets/styles/sidebar.scss @@ -0,0 +1,227 @@ +#app { + + .main-container { + height: 100%; + transition: margin-left .28s; + margin-left: $base-sidebar-width; + position: relative; + } + + .sidebarHide { + margin-left: 0!important; + } + + .sidebar-container { + -webkit-transition: width .28s; + transition: width 0.28s; + width: $base-sidebar-width !important; + background-color: $base-menu-background; + height: 100%; + position: fixed; + font-size: 0px; + top: 0; + bottom: 0; + left: 0; + z-index: 1001; + overflow: hidden; + -webkit-box-shadow: 2px 0 6px rgba(0,21,41,.35); + box-shadow: 2px 0 6px rgba(0,21,41,.35); + + // reset element-ui css + .horizontal-collapse-transition { + transition: 0s width ease-in-out, 0s padding-left ease-in-out, 0s padding-right ease-in-out; + } + + .scrollbar-wrapper { + overflow-x: hidden !important; + } + + .el-scrollbar__bar.is-vertical { + right: 0px; + } + + .el-scrollbar { + height: 100%; + } + + &.has-logo { + .el-scrollbar { + height: calc(100% - 50px); + } + } + + .is-horizontal { + display: none; + } + + a { + display: inline-block; + width: 100%; + overflow: hidden; + } + + .svg-icon { + margin-right: 16px; + } + + .el-menu { + border: none; + height: 100%; + width: 100% !important; + } + + .el-menu-item, .el-submenu__title { + overflow: hidden !important; + text-overflow: ellipsis !important; + white-space: nowrap !important; + } + + // menu hover + .submenu-title-noDropdown, + .el-submenu__title { + &:hover { + background-color: rgba(0, 0, 0, 0.06) !important; + } + } + + & .theme-dark .is-active > .el-submenu__title { + color: $base-menu-color-active !important; + } + + & .nest-menu .el-submenu>.el-submenu__title, + & .el-submenu .el-menu-item { + min-width: $base-sidebar-width !important; + + &:hover { + background-color: rgba(0, 0, 0, 0.06) !important; + } + } + + & .theme-dark .nest-menu .el-submenu>.el-submenu__title, + & .theme-dark .el-submenu .el-menu-item { + background-color: $base-sub-menu-background !important; + + &:hover { + background-color: $base-sub-menu-hover !important; + } + } + } + + .hideSidebar { + .sidebar-container { + width: 54px !important; + } + + .main-container { + margin-left: 54px; + } + + .submenu-title-noDropdown { + padding: 0 !important; + position: relative; + + .el-tooltip { + padding: 0 !important; + + .svg-icon { + margin-left: 20px; + } + } + } + + .el-submenu { + overflow: hidden; + + &>.el-submenu__title { + padding: 0 !important; + + .svg-icon { + margin-left: 20px; + } + + } + } + + .el-menu--collapse { + .el-submenu { + &>.el-submenu__title { + &>span { + height: 0; + width: 0; + overflow: hidden; + visibility: hidden; + display: inline-block; + } + } + } + } + } + + .el-menu--collapse .el-menu .el-submenu { + min-width: $base-sidebar-width !important; + } + + // mobile responsive + .mobile { + .main-container { + margin-left: 0px; + } + + .sidebar-container { + transition: transform .28s; + width: $base-sidebar-width !important; + } + + &.hideSidebar { + .sidebar-container { + pointer-events: none; + transition-duration: 0.3s; + transform: translate3d(-$base-sidebar-width, 0, 0); + } + } + } + + .withoutAnimation { + + .main-container, + .sidebar-container { + transition: none; + } + } +} + +// when menu collapsed +.el-menu--vertical { + &>.el-menu { + .svg-icon { + margin-right: 16px; + } + } + + .nest-menu .el-submenu>.el-submenu__title, + .el-menu-item { + &:hover { + // you can use $subMenuHover + background-color: rgba(0, 0, 0, 0.06) !important; + } + } + + // the scroll bar appears when the subMenu is too long + >.el-menu--popup { + max-height: 100vh; + overflow-y: auto; + + &::-webkit-scrollbar-track-piece { + background: #d3dce6; + } + + &::-webkit-scrollbar { + width: 6px; + } + + &::-webkit-scrollbar-thumb { + background: #99a9bf; + border-radius: 20px; + } + } +} diff --git a/zzyl-ui/src/assets/styles/transition.scss b/zzyl-ui/src/assets/styles/transition.scss new file mode 100644 index 0000000..073f8c6 --- /dev/null +++ b/zzyl-ui/src/assets/styles/transition.scss @@ -0,0 +1,49 @@ +// global transition css + +/* fade */ +.fade-enter-active, +.fade-leave-active { + transition: opacity 0.28s; +} + +.fade-enter, +.fade-leave-active { + opacity: 0; +} + +/* fade-transform */ +.fade-transform--move, +.fade-transform-leave-active, +.fade-transform-enter-active { + transition: all .5s; +} + +.fade-transform-enter { + opacity: 0; + transform: translateX(-30px); +} + +.fade-transform-leave-to { + opacity: 0; + transform: translateX(30px); +} + +/* breadcrumb transition */ +.breadcrumb-enter-active, +.breadcrumb-leave-active { + transition: all .5s; +} + +.breadcrumb-enter, +.breadcrumb-leave-active { + opacity: 0; + transform: translateX(20px); +} + +.breadcrumb-move { + transition: all .5s; +} + +.breadcrumb-leave-active { + position: absolute; +} diff --git a/zzyl-ui/src/assets/styles/variables.scss b/zzyl-ui/src/assets/styles/variables.scss new file mode 100644 index 0000000..34484d4 --- /dev/null +++ b/zzyl-ui/src/assets/styles/variables.scss @@ -0,0 +1,54 @@ +// base color +$blue:#324157; +$light-blue:#3A71A8; +$red:#C03639; +$pink: #E65D6E; +$green: #30B08F; +$tiffany: #4AB7BD; +$yellow:#FEC171; +$panGreen: #30B08F; + +// 默认菜单主题风格 +$base-menu-color:#bfcbd9; +$base-menu-color-active:#f4f4f5; +$base-menu-background:#304156; +$base-logo-title-color: #ffffff; + +$base-menu-light-color:rgba(0,0,0,.70); +$base-menu-light-background:#ffffff; +$base-logo-light-title-color: #001529; + +$base-sub-menu-background:#1f2d3d; +$base-sub-menu-hover:#001528; + +// 自定义暗色菜单风格 +/** +$base-menu-color:hsla(0,0%,100%,.65); +$base-menu-color-active:#fff; +$base-menu-background:#001529; +$base-logo-title-color: #ffffff; + +$base-menu-light-color:rgba(0,0,0,.70); +$base-menu-light-background:#ffffff; +$base-logo-light-title-color: #001529; + +$base-sub-menu-background:#000c17; +$base-sub-menu-hover:#001528; +*/ + +$base-sidebar-width: 200px; + +// the :export directive is the magic sauce for webpack +// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass +:export { + menuColor: $base-menu-color; + menuLightColor: $base-menu-light-color; + menuColorActive: $base-menu-color-active; + menuBackground: $base-menu-background; + menuLightBackground: $base-menu-light-background; + subMenuBackground: $base-sub-menu-background; + subMenuHover: $base-sub-menu-hover; + sideBarWidth: $base-sidebar-width; + logoTitleColor: $base-logo-title-color; + logoLightTitleColor: $base-logo-light-title-color +} diff --git a/zzyl-ui/src/components/Breadcrumb/index.vue b/zzyl-ui/src/components/Breadcrumb/index.vue new file mode 100644 index 0000000..1696f54 --- /dev/null +++ b/zzyl-ui/src/components/Breadcrumb/index.vue @@ -0,0 +1,74 @@ + + + + + diff --git a/zzyl-ui/src/components/Crontab/day.vue b/zzyl-ui/src/components/Crontab/day.vue new file mode 100644 index 0000000..fe3eaf0 --- /dev/null +++ b/zzyl-ui/src/components/Crontab/day.vue @@ -0,0 +1,161 @@ + + + diff --git a/zzyl-ui/src/components/Crontab/hour.vue b/zzyl-ui/src/components/Crontab/hour.vue new file mode 100644 index 0000000..3216c33 --- /dev/null +++ b/zzyl-ui/src/components/Crontab/hour.vue @@ -0,0 +1,120 @@ + + + diff --git a/zzyl-ui/src/components/Crontab/index.vue b/zzyl-ui/src/components/Crontab/index.vue new file mode 100644 index 0000000..3963df2 --- /dev/null +++ b/zzyl-ui/src/components/Crontab/index.vue @@ -0,0 +1,430 @@ + + + + diff --git a/zzyl-ui/src/components/Crontab/min.vue b/zzyl-ui/src/components/Crontab/min.vue new file mode 100644 index 0000000..43cab90 --- /dev/null +++ b/zzyl-ui/src/components/Crontab/min.vue @@ -0,0 +1,116 @@ + + + \ No newline at end of file diff --git a/zzyl-ui/src/components/Crontab/month.vue b/zzyl-ui/src/components/Crontab/month.vue new file mode 100644 index 0000000..fd0ac38 --- /dev/null +++ b/zzyl-ui/src/components/Crontab/month.vue @@ -0,0 +1,114 @@ + + + diff --git a/zzyl-ui/src/components/Crontab/result.vue b/zzyl-ui/src/components/Crontab/result.vue new file mode 100644 index 0000000..aea6e0e --- /dev/null +++ b/zzyl-ui/src/components/Crontab/result.vue @@ -0,0 +1,559 @@ + + + diff --git a/zzyl-ui/src/components/Crontab/second.vue b/zzyl-ui/src/components/Crontab/second.vue new file mode 100644 index 0000000..e7b7761 --- /dev/null +++ b/zzyl-ui/src/components/Crontab/second.vue @@ -0,0 +1,117 @@ + + + diff --git a/zzyl-ui/src/components/Crontab/week.vue b/zzyl-ui/src/components/Crontab/week.vue new file mode 100644 index 0000000..1cec700 --- /dev/null +++ b/zzyl-ui/src/components/Crontab/week.vue @@ -0,0 +1,202 @@ + + + diff --git a/zzyl-ui/src/components/Crontab/year.vue b/zzyl-ui/src/components/Crontab/year.vue new file mode 100644 index 0000000..5487a6c --- /dev/null +++ b/zzyl-ui/src/components/Crontab/year.vue @@ -0,0 +1,131 @@ + + + diff --git a/zzyl-ui/src/components/DictData/index.js b/zzyl-ui/src/components/DictData/index.js new file mode 100644 index 0000000..7b85d4a --- /dev/null +++ b/zzyl-ui/src/components/DictData/index.js @@ -0,0 +1,49 @@ +import Vue from 'vue' +import store from '@/store' +import DataDict from '@/utils/dict' +import { getDicts as getDicts } from '@/api/system/dict/data' + +function searchDictByKey(dict, key) { + if (key == null && key == "") { + return null + } + try { + for (let i = 0; i < dict.length; i++) { + if (dict[i].key == key) { + return dict[i].value + } + } + } catch (e) { + return null + } +} + +function install() { + Vue.use(DataDict, { + metas: { + '*': { + labelField: 'dictLabel', + valueField: 'dictValue', + request(dictMeta) { + const storeDict = searchDictByKey(store.getters.dict, dictMeta.type) + if (storeDict) { + return new Promise(resolve => { resolve(storeDict) }) + } else { + return new Promise((resolve, reject) => { + getDicts(dictMeta.type).then(res => { + store.dispatch('dict/setDict', { key: dictMeta.type, value: res.data }) + resolve(res.data) + }).catch(error => { + reject(error) + }) + }) + } + }, + }, + }, + }) +} + +export default { + install, +} \ No newline at end of file diff --git a/zzyl-ui/src/components/DictTag/index.vue b/zzyl-ui/src/components/DictTag/index.vue new file mode 100644 index 0000000..6b5b230 --- /dev/null +++ b/zzyl-ui/src/components/DictTag/index.vue @@ -0,0 +1,89 @@ + + + + diff --git a/zzyl-ui/src/components/Editor/index.vue b/zzyl-ui/src/components/Editor/index.vue new file mode 100644 index 0000000..8981d76 --- /dev/null +++ b/zzyl-ui/src/components/Editor/index.vue @@ -0,0 +1,274 @@ + + + + + diff --git a/zzyl-ui/src/components/FileUpload/index.vue b/zzyl-ui/src/components/FileUpload/index.vue new file mode 100644 index 0000000..c7f6b0a --- /dev/null +++ b/zzyl-ui/src/components/FileUpload/index.vue @@ -0,0 +1,216 @@ + + + + + diff --git a/zzyl-ui/src/components/Hamburger/index.vue b/zzyl-ui/src/components/Hamburger/index.vue new file mode 100644 index 0000000..368b002 --- /dev/null +++ b/zzyl-ui/src/components/Hamburger/index.vue @@ -0,0 +1,44 @@ + + + + + diff --git a/zzyl-ui/src/components/HeaderSearch/index.vue b/zzyl-ui/src/components/HeaderSearch/index.vue new file mode 100644 index 0000000..7d6780b --- /dev/null +++ b/zzyl-ui/src/components/HeaderSearch/index.vue @@ -0,0 +1,198 @@ + + + + + diff --git a/zzyl-ui/src/components/IconSelect/index.vue b/zzyl-ui/src/components/IconSelect/index.vue new file mode 100644 index 0000000..8dadc02 --- /dev/null +++ b/zzyl-ui/src/components/IconSelect/index.vue @@ -0,0 +1,104 @@ + + + + + + diff --git a/zzyl-ui/src/components/IconSelect/requireIcons.js b/zzyl-ui/src/components/IconSelect/requireIcons.js new file mode 100644 index 0000000..99e5c54 --- /dev/null +++ b/zzyl-ui/src/components/IconSelect/requireIcons.js @@ -0,0 +1,11 @@ + +const req = require.context('../../assets/icons/svg', false, /\.svg$/) +const requireAll = requireContext => requireContext.keys() + +const re = /\.\/(.*)\.svg/ + +const icons = requireAll(req).map(i => { + return i.match(re)[1] +}) + +export default icons diff --git a/zzyl-ui/src/components/ImagePreview/index.vue b/zzyl-ui/src/components/ImagePreview/index.vue new file mode 100644 index 0000000..3c770c7 --- /dev/null +++ b/zzyl-ui/src/components/ImagePreview/index.vue @@ -0,0 +1,90 @@ + + + + + diff --git a/zzyl-ui/src/components/ImageUpload/index.vue b/zzyl-ui/src/components/ImageUpload/index.vue new file mode 100644 index 0000000..2e64c9b --- /dev/null +++ b/zzyl-ui/src/components/ImageUpload/index.vue @@ -0,0 +1,226 @@ + + + + + diff --git a/zzyl-ui/src/components/Pagination/index.vue b/zzyl-ui/src/components/Pagination/index.vue new file mode 100644 index 0000000..56f5a6b --- /dev/null +++ b/zzyl-ui/src/components/Pagination/index.vue @@ -0,0 +1,114 @@ + + + + + diff --git a/zzyl-ui/src/components/PanThumb/index.vue b/zzyl-ui/src/components/PanThumb/index.vue new file mode 100644 index 0000000..1bcf417 --- /dev/null +++ b/zzyl-ui/src/components/PanThumb/index.vue @@ -0,0 +1,142 @@ + + + + + diff --git a/zzyl-ui/src/components/ParentView/index.vue b/zzyl-ui/src/components/ParentView/index.vue new file mode 100644 index 0000000..7bf6148 --- /dev/null +++ b/zzyl-ui/src/components/ParentView/index.vue @@ -0,0 +1,3 @@ + diff --git a/zzyl-ui/src/components/RightPanel/index.vue b/zzyl-ui/src/components/RightPanel/index.vue new file mode 100644 index 0000000..5abeecb --- /dev/null +++ b/zzyl-ui/src/components/RightPanel/index.vue @@ -0,0 +1,106 @@ + + + + + diff --git a/zzyl-ui/src/components/RightToolbar/index.vue b/zzyl-ui/src/components/RightToolbar/index.vue new file mode 100644 index 0000000..67da293 --- /dev/null +++ b/zzyl-ui/src/components/RightToolbar/index.vue @@ -0,0 +1,129 @@ + + + diff --git a/zzyl-ui/src/components/RuoYi/Doc/index.vue b/zzyl-ui/src/components/RuoYi/Doc/index.vue new file mode 100644 index 0000000..75fa864 --- /dev/null +++ b/zzyl-ui/src/components/RuoYi/Doc/index.vue @@ -0,0 +1,21 @@ + + + \ No newline at end of file diff --git a/zzyl-ui/src/components/RuoYi/Git/index.vue b/zzyl-ui/src/components/RuoYi/Git/index.vue new file mode 100644 index 0000000..bdafbae --- /dev/null +++ b/zzyl-ui/src/components/RuoYi/Git/index.vue @@ -0,0 +1,21 @@ + + + \ No newline at end of file diff --git a/zzyl-ui/src/components/Screenfull/index.vue b/zzyl-ui/src/components/Screenfull/index.vue new file mode 100644 index 0000000..d4e539c --- /dev/null +++ b/zzyl-ui/src/components/Screenfull/index.vue @@ -0,0 +1,57 @@ + + + + + diff --git a/zzyl-ui/src/components/SizeSelect/index.vue b/zzyl-ui/src/components/SizeSelect/index.vue new file mode 100644 index 0000000..069b5de --- /dev/null +++ b/zzyl-ui/src/components/SizeSelect/index.vue @@ -0,0 +1,56 @@ + + + diff --git a/zzyl-ui/src/components/SvgIcon/index.vue b/zzyl-ui/src/components/SvgIcon/index.vue new file mode 100644 index 0000000..e4bf5ad --- /dev/null +++ b/zzyl-ui/src/components/SvgIcon/index.vue @@ -0,0 +1,61 @@ + + + + + diff --git a/zzyl-ui/src/components/ThemePicker/index.vue b/zzyl-ui/src/components/ThemePicker/index.vue new file mode 100644 index 0000000..1714e1f --- /dev/null +++ b/zzyl-ui/src/components/ThemePicker/index.vue @@ -0,0 +1,173 @@ + + + + + diff --git a/zzyl-ui/src/components/TopNav/index.vue b/zzyl-ui/src/components/TopNav/index.vue new file mode 100644 index 0000000..86a91c4 --- /dev/null +++ b/zzyl-ui/src/components/TopNav/index.vue @@ -0,0 +1,195 @@ + + + + + diff --git a/zzyl-ui/src/components/iFrame/index.vue b/zzyl-ui/src/components/iFrame/index.vue new file mode 100644 index 0000000..426857f --- /dev/null +++ b/zzyl-ui/src/components/iFrame/index.vue @@ -0,0 +1,36 @@ + + + diff --git a/zzyl-ui/src/layout/components/Navbar.vue b/zzyl-ui/src/layout/components/Navbar.vue new file mode 100644 index 0000000..466cd98 --- /dev/null +++ b/zzyl-ui/src/layout/components/Navbar.vue @@ -0,0 +1,200 @@ + + + + + diff --git a/zzyl-ui/src/layout/components/Settings/index.vue b/zzyl-ui/src/layout/components/Settings/index.vue new file mode 100644 index 0000000..bb3c9ce --- /dev/null +++ b/zzyl-ui/src/layout/components/Settings/index.vue @@ -0,0 +1,260 @@ + + + + + diff --git a/zzyl-ui/src/layout/components/Sidebar/FixiOSBug.js b/zzyl-ui/src/layout/components/Sidebar/FixiOSBug.js new file mode 100644 index 0000000..6823726 --- /dev/null +++ b/zzyl-ui/src/layout/components/Sidebar/FixiOSBug.js @@ -0,0 +1,25 @@ +export default { + computed: { + device() { + return this.$store.state.app.device + } + }, + mounted() { + // In order to fix the click on menu on the ios device will trigger the mouseleave bug + this.fixBugIniOS() + }, + methods: { + fixBugIniOS() { + const $subMenu = this.$refs.subMenu + if ($subMenu) { + const handleMouseleave = $subMenu.handleMouseleave + $subMenu.handleMouseleave = (e) => { + if (this.device === 'mobile') { + return + } + handleMouseleave(e) + } + } + } + } +} diff --git a/zzyl-ui/src/layout/components/Sidebar/Item.vue b/zzyl-ui/src/layout/components/Sidebar/Item.vue new file mode 100644 index 0000000..be3285d --- /dev/null +++ b/zzyl-ui/src/layout/components/Sidebar/Item.vue @@ -0,0 +1,33 @@ + diff --git a/zzyl-ui/src/layout/components/Sidebar/Link.vue b/zzyl-ui/src/layout/components/Sidebar/Link.vue new file mode 100644 index 0000000..8b0bc93 --- /dev/null +++ b/zzyl-ui/src/layout/components/Sidebar/Link.vue @@ -0,0 +1,43 @@ + + + diff --git a/zzyl-ui/src/layout/components/Sidebar/Logo.vue b/zzyl-ui/src/layout/components/Sidebar/Logo.vue new file mode 100644 index 0000000..2774cc8 --- /dev/null +++ b/zzyl-ui/src/layout/components/Sidebar/Logo.vue @@ -0,0 +1,93 @@ + + + + + diff --git a/zzyl-ui/src/layout/components/Sidebar/SidebarItem.vue b/zzyl-ui/src/layout/components/Sidebar/SidebarItem.vue new file mode 100644 index 0000000..82ba407 --- /dev/null +++ b/zzyl-ui/src/layout/components/Sidebar/SidebarItem.vue @@ -0,0 +1,100 @@ + + + diff --git a/zzyl-ui/src/layout/components/Sidebar/index.vue b/zzyl-ui/src/layout/components/Sidebar/index.vue new file mode 100644 index 0000000..51d0839 --- /dev/null +++ b/zzyl-ui/src/layout/components/Sidebar/index.vue @@ -0,0 +1,57 @@ + + + diff --git a/zzyl-ui/src/layout/components/TagsView/ScrollPane.vue b/zzyl-ui/src/layout/components/TagsView/ScrollPane.vue new file mode 100644 index 0000000..bb753a1 --- /dev/null +++ b/zzyl-ui/src/layout/components/TagsView/ScrollPane.vue @@ -0,0 +1,94 @@ + + + + + diff --git a/zzyl-ui/src/layout/components/TagsView/index.vue b/zzyl-ui/src/layout/components/TagsView/index.vue new file mode 100644 index 0000000..96585a5 --- /dev/null +++ b/zzyl-ui/src/layout/components/TagsView/index.vue @@ -0,0 +1,332 @@ + + + + + + + diff --git a/zzyl-ui/src/layout/components/index.js b/zzyl-ui/src/layout/components/index.js new file mode 100644 index 0000000..104bd3a --- /dev/null +++ b/zzyl-ui/src/layout/components/index.js @@ -0,0 +1,5 @@ +export { default as AppMain } from './AppMain' +export { default as Navbar } from './Navbar' +export { default as Settings } from './Settings' +export { default as Sidebar } from './Sidebar/index.vue' +export { default as TagsView } from './TagsView/index.vue' diff --git a/zzyl-ui/src/layout/index.vue b/zzyl-ui/src/layout/index.vue new file mode 100644 index 0000000..dba4393 --- /dev/null +++ b/zzyl-ui/src/layout/index.vue @@ -0,0 +1,111 @@ + + + + + diff --git a/zzyl-ui/src/layout/mixin/ResizeHandler.js b/zzyl-ui/src/layout/mixin/ResizeHandler.js new file mode 100644 index 0000000..e8d0df8 --- /dev/null +++ b/zzyl-ui/src/layout/mixin/ResizeHandler.js @@ -0,0 +1,45 @@ +import store from '@/store' + +const { body } = document +const WIDTH = 992 // refer to Bootstrap's responsive design + +export default { + watch: { + $route(route) { + if (this.device === 'mobile' && this.sidebar.opened) { + store.dispatch('app/closeSideBar', { withoutAnimation: false }) + } + } + }, + beforeMount() { + window.addEventListener('resize', this.$_resizeHandler) + }, + beforeDestroy() { + window.removeEventListener('resize', this.$_resizeHandler) + }, + mounted() { + const isMobile = this.$_isMobile() + if (isMobile) { + store.dispatch('app/toggleDevice', 'mobile') + store.dispatch('app/closeSideBar', { withoutAnimation: true }) + } + }, + methods: { + // use $_ for mixins properties + // https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential + $_isMobile() { + const rect = body.getBoundingClientRect() + return rect.width - 1 < WIDTH + }, + $_resizeHandler() { + if (!document.hidden) { + const isMobile = this.$_isMobile() + store.dispatch('app/toggleDevice', isMobile ? 'mobile' : 'desktop') + + if (isMobile) { + store.dispatch('app/closeSideBar', { withoutAnimation: true }) + } + } + } + } +} diff --git a/zzyl-ui/src/main.js b/zzyl-ui/src/main.js new file mode 100644 index 0000000..13c6cf2 --- /dev/null +++ b/zzyl-ui/src/main.js @@ -0,0 +1,86 @@ +import Vue from 'vue' + +import Cookies from 'js-cookie' + +import Element from 'element-ui' +import './assets/styles/element-variables.scss' + +import '@/assets/styles/index.scss' // global css +import '@/assets/styles/ruoyi.scss' // ruoyi css +import App from './App' +import store from './store' +import router from './router' +import directive from './directive' // directive +import plugins from './plugins' // plugins +import { download } from '@/utils/request' + +import './assets/icons' // icon +import './permission' // permission control +import { getDicts } from "@/api/system/dict/data"; +import { getConfigKey } from "@/api/system/config"; +import { parseTime, resetForm, addDateRange, selectDictLabel, selectDictLabels, handleTree } from "@/utils/ruoyi"; +// 分页组件 +import Pagination from "@/components/Pagination"; +// 自定义表格工具组件 +import RightToolbar from "@/components/RightToolbar" +// 富文本组件 +import Editor from "@/components/Editor" +// 文件上传组件 +import FileUpload from "@/components/FileUpload" +// 图片上传组件 +import ImageUpload from "@/components/ImageUpload" +// 图片预览组件 +import ImagePreview from "@/components/ImagePreview" +// 字典标签组件 +import DictTag from '@/components/DictTag' +// 头部标签组件 +import VueMeta from 'vue-meta' +// 字典数据组件 +import DictData from '@/components/DictData' + +// 全局方法挂载 +Vue.prototype.getDicts = getDicts +Vue.prototype.getConfigKey = getConfigKey +Vue.prototype.parseTime = parseTime +Vue.prototype.resetForm = resetForm +Vue.prototype.addDateRange = addDateRange +Vue.prototype.selectDictLabel = selectDictLabel +Vue.prototype.selectDictLabels = selectDictLabels +Vue.prototype.download = download +Vue.prototype.handleTree = handleTree + +// 全局组件挂载 +Vue.component('DictTag', DictTag) +Vue.component('Pagination', Pagination) +Vue.component('RightToolbar', RightToolbar) +Vue.component('Editor', Editor) +Vue.component('FileUpload', FileUpload) +Vue.component('ImageUpload', ImageUpload) +Vue.component('ImagePreview', ImagePreview) + +Vue.use(directive) +Vue.use(plugins) +Vue.use(VueMeta) +DictData.install() + +/** + * If you don't want to use mock-server + * you want to use MockJs for mock api + * you can execute: mockXHR() + * + * Currently MockJs will be used in the production environment, + * please remove it before going online! ! ! + */ + +Vue.use(Element, { + size: Cookies.get('size') || 'medium' // set element-ui default size +}) + +Vue.config.productionTip = false + +new Vue({ + el: '#app', + router, + store, + render: h => h(App) +}) diff --git a/zzyl-ui/src/permission.js b/zzyl-ui/src/permission.js new file mode 100644 index 0000000..c568979 --- /dev/null +++ b/zzyl-ui/src/permission.js @@ -0,0 +1,58 @@ +import router from './router' +import store from './store' +import { Message } from 'element-ui' +import NProgress from 'nprogress' +import 'nprogress/nprogress.css' +import { getToken } from '@/utils/auth' +import { isRelogin } from '@/utils/request' + +NProgress.configure({ showSpinner: false }) + +const whiteList = ['/login', '/register'] + +router.beforeEach((to, from, next) => { + NProgress.start() + if (getToken()) { + to.meta.title && store.dispatch('settings/setTitle', to.meta.title) + /* has token*/ + if (to.path === '/login') { + next({ path: '/' }) + NProgress.done() + } else if (whiteList.indexOf(to.path) !== -1) { + next() + } else { + if (store.getters.roles.length === 0) { + isRelogin.show = true + // 判断当前用户是否已拉取完user_info信息 + store.dispatch('GetInfo').then(() => { + isRelogin.show = false + store.dispatch('GenerateRoutes').then(accessRoutes => { + // 根据roles权限生成可访问的路由表 + router.addRoutes(accessRoutes) // 动态添加可访问路由表 + next({ ...to, replace: true }) // hack方法 确保addRoutes已完成 + }) + }).catch(err => { + store.dispatch('LogOut').then(() => { + Message.error(err) + next({ path: '/' }) + }) + }) + } else { + next() + } + } + } else { + // 没有token + if (whiteList.indexOf(to.path) !== -1) { + // 在免登录白名单,直接进入 + next() + } else { + next(`/login?redirect=${encodeURIComponent(to.fullPath)}`) // 否则全部重定向到登录页 + NProgress.done() + } + } +}) + +router.afterEach(() => { + NProgress.done() +}) diff --git a/zzyl-ui/src/plugins/auth.js b/zzyl-ui/src/plugins/auth.js new file mode 100644 index 0000000..6c6bc24 --- /dev/null +++ b/zzyl-ui/src/plugins/auth.js @@ -0,0 +1,60 @@ +import store from '@/store' + +function authPermission(permission) { + const all_permission = "*:*:*"; + const permissions = store.getters && store.getters.permissions + if (permission && permission.length > 0) { + return permissions.some(v => { + return all_permission === v || v === permission + }) + } else { + return false + } +} + +function authRole(role) { + const super_admin = "admin"; + const roles = store.getters && store.getters.roles + if (role && role.length > 0) { + return roles.some(v => { + return super_admin === v || v === role + }) + } else { + return false + } +} + +export default { + // 验证用户是否具备某权限 + hasPermi(permission) { + return authPermission(permission); + }, + // 验证用户是否含有指定权限,只需包含其中一个 + hasPermiOr(permissions) { + return permissions.some(item => { + return authPermission(item) + }) + }, + // 验证用户是否含有指定权限,必须全部拥有 + hasPermiAnd(permissions) { + return permissions.every(item => { + return authPermission(item) + }) + }, + // 验证用户是否具备某角色 + hasRole(role) { + return authRole(role); + }, + // 验证用户是否含有指定角色,只需包含其中一个 + hasRoleOr(roles) { + return roles.some(item => { + return authRole(item) + }) + }, + // 验证用户是否含有指定角色,必须全部拥有 + hasRoleAnd(roles) { + return roles.every(item => { + return authRole(item) + }) + } +} diff --git a/zzyl-ui/src/plugins/cache.js b/zzyl-ui/src/plugins/cache.js new file mode 100644 index 0000000..6b5c00b --- /dev/null +++ b/zzyl-ui/src/plugins/cache.js @@ -0,0 +1,77 @@ +const sessionCache = { + set (key, value) { + if (!sessionStorage) { + return + } + if (key != null && value != null) { + sessionStorage.setItem(key, value) + } + }, + get (key) { + if (!sessionStorage) { + return null + } + if (key == null) { + return null + } + return sessionStorage.getItem(key) + }, + setJSON (key, jsonValue) { + if (jsonValue != null) { + this.set(key, JSON.stringify(jsonValue)) + } + }, + getJSON (key) { + const value = this.get(key) + if (value != null) { + return JSON.parse(value) + } + }, + remove (key) { + sessionStorage.removeItem(key); + } +} +const localCache = { + set (key, value) { + if (!localStorage) { + return + } + if (key != null && value != null) { + localStorage.setItem(key, value) + } + }, + get (key) { + if (!localStorage) { + return null + } + if (key == null) { + return null + } + return localStorage.getItem(key) + }, + setJSON (key, jsonValue) { + if (jsonValue != null) { + this.set(key, JSON.stringify(jsonValue)) + } + }, + getJSON (key) { + const value = this.get(key) + if (value != null) { + return JSON.parse(value) + } + }, + remove (key) { + localStorage.removeItem(key); + } +} + +export default { + /** + * 会话级缓存 + */ + session: sessionCache, + /** + * 本地缓存 + */ + local: localCache +} diff --git a/zzyl-ui/src/plugins/download.js b/zzyl-ui/src/plugins/download.js new file mode 100644 index 0000000..42acd00 --- /dev/null +++ b/zzyl-ui/src/plugins/download.js @@ -0,0 +1,79 @@ +import axios from 'axios' +import {Loading, Message} from 'element-ui' +import { saveAs } from 'file-saver' +import { getToken } from '@/utils/auth' +import errorCode from '@/utils/errorCode' +import { blobValidate } from "@/utils/ruoyi"; + +const baseURL = process.env.VUE_APP_BASE_API +let downloadLoadingInstance; + +export default { + name(name, isDelete = true) { + var url = baseURL + "/common/download?fileName=" + encodeURIComponent(name) + "&delete=" + isDelete + axios({ + method: 'get', + url: url, + responseType: 'blob', + headers: { 'Authorization': 'Bearer ' + getToken() } + }).then((res) => { + const isBlob = blobValidate(res.data); + if (isBlob) { + const blob = new Blob([res.data]) + this.saveAs(blob, decodeURIComponent(res.headers['download-filename'])) + } else { + this.printErrMsg(res.data); + } + }) + }, + resource(resource) { + var url = baseURL + "/common/download/resource?resource=" + encodeURIComponent(resource); + axios({ + method: 'get', + url: url, + responseType: 'blob', + headers: { 'Authorization': 'Bearer ' + getToken() } + }).then((res) => { + const isBlob = blobValidate(res.data); + if (isBlob) { + const blob = new Blob([res.data]) + this.saveAs(blob, decodeURIComponent(res.headers['download-filename'])) + } else { + this.printErrMsg(res.data); + } + }) + }, + zip(url, name) { + var url = baseURL + url + downloadLoadingInstance = Loading.service({ text: "正在下载数据,请稍候", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)", }) + axios({ + method: 'get', + url: url, + responseType: 'blob', + headers: { 'Authorization': 'Bearer ' + getToken() } + }).then((res) => { + const isBlob = blobValidate(res.data); + if (isBlob) { + const blob = new Blob([res.data], { type: 'application/zip' }) + this.saveAs(blob, name) + } else { + this.printErrMsg(res.data); + } + downloadLoadingInstance.close(); + }).catch((r) => { + console.error(r) + Message.error('下载文件出现错误,请联系管理员!') + downloadLoadingInstance.close(); + }) + }, + saveAs(text, name, opts) { + saveAs(text, name, opts); + }, + async printErrMsg(data) { + const resText = await data.text(); + const rspObj = JSON.parse(resText); + const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default'] + Message.error(errMsg); + } +} + diff --git a/zzyl-ui/src/plugins/index.js b/zzyl-ui/src/plugins/index.js new file mode 100644 index 0000000..d000f2d --- /dev/null +++ b/zzyl-ui/src/plugins/index.js @@ -0,0 +1,20 @@ +import tab from './tab' +import auth from './auth' +import cache from './cache' +import modal from './modal' +import download from './download' + +export default { + install(Vue) { + // 页签操作 + Vue.prototype.$tab = tab + // 认证对象 + Vue.prototype.$auth = auth + // 缓存对象 + Vue.prototype.$cache = cache + // 模态框对象 + Vue.prototype.$modal = modal + // 下载文件 + Vue.prototype.$download = download + } +} diff --git a/zzyl-ui/src/plugins/modal.js b/zzyl-ui/src/plugins/modal.js new file mode 100644 index 0000000..b37ca14 --- /dev/null +++ b/zzyl-ui/src/plugins/modal.js @@ -0,0 +1,83 @@ +import { Message, MessageBox, Notification, Loading } from 'element-ui' + +let loadingInstance; + +export default { + // 消息提示 + msg(content) { + Message.info(content) + }, + // 错误消息 + msgError(content) { + Message.error(content) + }, + // 成功消息 + msgSuccess(content) { + Message.success(content) + }, + // 警告消息 + msgWarning(content) { + Message.warning(content) + }, + // 弹出提示 + alert(content) { + MessageBox.alert(content, "系统提示") + }, + // 错误提示 + alertError(content) { + MessageBox.alert(content, "系统提示", { type: 'error' }) + }, + // 成功提示 + alertSuccess(content) { + MessageBox.alert(content, "系统提示", { type: 'success' }) + }, + // 警告提示 + alertWarning(content) { + MessageBox.alert(content, "系统提示", { type: 'warning' }) + }, + // 通知提示 + notify(content) { + Notification.info(content) + }, + // 错误通知 + notifyError(content) { + Notification.error(content); + }, + // 成功通知 + notifySuccess(content) { + Notification.success(content) + }, + // 警告通知 + notifyWarning(content) { + Notification.warning(content) + }, + // 确认窗体 + confirm(content) { + return MessageBox.confirm(content, "系统提示", { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: "warning", + }) + }, + // 提交内容 + prompt(content) { + return MessageBox.prompt(content, "系统提示", { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: "warning", + }) + }, + // 打开遮罩层 + loading(content) { + loadingInstance = Loading.service({ + lock: true, + text: content, + spinner: "el-icon-loading", + background: "rgba(0, 0, 0, 0.7)", + }) + }, + // 关闭遮罩层 + closeLoading() { + loadingInstance.close(); + } +} diff --git a/zzyl-ui/src/plugins/tab.js b/zzyl-ui/src/plugins/tab.js new file mode 100644 index 0000000..fcde419 --- /dev/null +++ b/zzyl-ui/src/plugins/tab.js @@ -0,0 +1,71 @@ +import store from '@/store' +import router from '@/router'; + +export default { + // 刷新当前tab页签 + refreshPage(obj) { + const { path, query, matched } = router.currentRoute; + if (obj === undefined) { + matched.forEach((m) => { + if (m.components && m.components.default && m.components.default.name) { + if (!['Layout', 'ParentView'].includes(m.components.default.name)) { + obj = { name: m.components.default.name, path: path, query: query }; + } + } + }); + } + return store.dispatch('tagsView/delCachedView', obj).then(() => { + const { path, query } = obj + router.replace({ + path: '/redirect' + path, + query: query + }) + }) + }, + // 关闭当前tab页签,打开新页签 + closeOpenPage(obj) { + store.dispatch("tagsView/delView", router.currentRoute); + if (obj !== undefined) { + return router.push(obj); + } + }, + // 关闭指定tab页签 + closePage(obj) { + if (obj === undefined) { + return store.dispatch('tagsView/delView', router.currentRoute).then(({ visitedViews }) => { + const latestView = visitedViews.slice(-1)[0] + if (latestView) { + return router.push(latestView.fullPath) + } + return router.push('/'); + }); + } + return store.dispatch('tagsView/delView', obj); + }, + // 关闭所有tab页签 + closeAllPage() { + return store.dispatch('tagsView/delAllViews'); + }, + // 关闭左侧tab页签 + closeLeftPage(obj) { + return store.dispatch('tagsView/delLeftTags', obj || router.currentRoute); + }, + // 关闭右侧tab页签 + closeRightPage(obj) { + return store.dispatch('tagsView/delRightTags', obj || router.currentRoute); + }, + // 关闭其他tab页签 + closeOtherPage(obj) { + return store.dispatch('tagsView/delOthersViews', obj || router.currentRoute); + }, + // 添加tab页签 + openPage(title, url, params) { + const obj = { path: url, meta: { title: title } } + store.dispatch('tagsView/addView', obj); + return router.push({ path: url, query: params }); + }, + // 修改tab页签 + updatePage(obj) { + return store.dispatch('tagsView/updateVisitedView', obj); + } +} diff --git a/zzyl-ui/src/router/index.js b/zzyl-ui/src/router/index.js new file mode 100644 index 0000000..71907b6 --- /dev/null +++ b/zzyl-ui/src/router/index.js @@ -0,0 +1,183 @@ +import Vue from 'vue' +import Router from 'vue-router' + +Vue.use(Router) + +/* Layout */ +import Layout from '@/layout' + +/** + * Note: 路由配置项 + * + * hidden: true // 当设置 true 的时候该路由不会再侧边栏出现 如401,login等页面,或者如一些编辑页面/edit/1 + * alwaysShow: true // 当你一个路由下面的 children 声明的路由大于1个时,自动会变成嵌套的模式--如组件页面 + * // 只有一个时,会将那个子路由当做根路由显示在侧边栏--如引导页面 + * // 若你想不管路由下面的 children 声明的个数都显示你的根路由 + * // 你可以设置 alwaysShow: true,这样它就会忽略之前定义的规则,一直显示根路由 + * redirect: noRedirect // 当设置 noRedirect 的时候该路由在面包屑导航中不可被点击 + * name:'router-name' // 设定路由的名字,一定要填写不然使用时会出现各种问题 + * query: '{"id": 1, "name": "ry"}' // 访问路由的默认传递参数 + * roles: ['admin', 'common'] // 访问路由的角色权限 + * permissions: ['a:a:a', 'b:b:b'] // 访问路由的菜单权限 + * meta : { + noCache: true // 如果设置为true,则不会被 缓存(默认 false) + title: 'title' // 设置该路由在侧边栏和面包屑中展示的名字 + icon: 'svg-name' // 设置该路由的图标,对应路径src/assets/icons/svg + breadcrumb: false // 如果设置为false,则不会在breadcrumb面包屑中显示 + activeMenu: '/system/user' // 当路由设置了该属性,则会高亮相对应的侧边栏。 + } + */ + +// 公共路由 +export const constantRoutes = [ + { + path: '/redirect', + component: Layout, + hidden: true, + children: [ + { + path: '/redirect/:path(.*)', + component: () => import('@/views/redirect') + } + ] + }, + { + path: '/login', + component: () => import('@/views/login'), + hidden: true + }, + { + path: '/register', + component: () => import('@/views/register'), + hidden: true + }, + { + path: '/404', + component: () => import('@/views/error/404'), + hidden: true + }, + { + path: '/401', + component: () => import('@/views/error/401'), + hidden: true + }, + { + path: '', + component: Layout, + redirect: 'index', + children: [ + { + path: 'index', + component: () => import('@/views/index'), + name: 'Index', + meta: { title: '首页', icon: 'dashboard', affix: true } + } + ] + }, + { + path: '/user', + component: Layout, + hidden: true, + redirect: 'noredirect', + children: [ + { + path: 'profile', + component: () => import('@/views/system/user/profile/index'), + name: 'Profile', + meta: { title: '个人中心', icon: 'user' } + } + ] + } +] + +// 动态路由,基于用户权限动态去加载 +export const dynamicRoutes = [ + { + path: '/system/user-auth', + component: Layout, + hidden: true, + permissions: ['system:user:edit'], + children: [ + { + path: 'role/:userId(\\d+)', + component: () => import('@/views/system/user/authRole'), + name: 'AuthRole', + meta: { title: '分配角色', activeMenu: '/system/user' } + } + ] + }, + { + path: '/system/role-auth', + component: Layout, + hidden: true, + permissions: ['system:role:edit'], + children: [ + { + path: 'user/:roleId(\\d+)', + component: () => import('@/views/system/role/authUser'), + name: 'AuthUser', + meta: { title: '分配用户', activeMenu: '/system/role' } + } + ] + }, + { + path: '/system/dict-data', + component: Layout, + hidden: true, + permissions: ['system:dict:list'], + children: [ + { + path: 'index/:dictId(\\d+)', + component: () => import('@/views/system/dict/data'), + name: 'Data', + meta: { title: '字典数据', activeMenu: '/system/dict' } + } + ] + }, + { + path: '/monitor/job-log', + component: Layout, + hidden: true, + permissions: ['monitor:job:list'], + children: [ + { + path: 'index/:jobId(\\d+)', + component: () => import('@/views/monitor/job/log'), + name: 'JobLog', + meta: { title: '调度日志', activeMenu: '/monitor/job' } + } + ] + }, + { + path: '/tool/gen-edit', + component: Layout, + hidden: true, + permissions: ['tool:gen:edit'], + children: [ + { + path: 'index/:tableId(\\d+)', + component: () => import('@/views/tool/gen/editTable'), + name: 'GenEdit', + meta: { title: '修改生成配置', activeMenu: '/tool/gen' } + } + ] + } +] + +// 防止连续点击多次路由报错 +let routerPush = Router.prototype.push; +let routerReplace = Router.prototype.replace; +// push +Router.prototype.push = function push(location) { + return routerPush.call(this, location).catch(err => err) +} +// replace +Router.prototype.replace = function push(location) { + return routerReplace.call(this, location).catch(err => err) +} + +export default new Router({ + mode: 'history', // 去掉url中的# + scrollBehavior: () => ({ y: 0 }), + routes: constantRoutes +}) diff --git a/zzyl-ui/src/settings.js b/zzyl-ui/src/settings.js new file mode 100644 index 0000000..6a0b09f --- /dev/null +++ b/zzyl-ui/src/settings.js @@ -0,0 +1,44 @@ +module.exports = { + /** + * 侧边栏主题 深色主题theme-dark,浅色主题theme-light + */ + sideTheme: 'theme-dark', + + /** + * 是否系统布局配置 + */ + showSettings: false, + + /** + * 是否显示顶部导航 + */ + topNav: false, + + /** + * 是否显示 tagsView + */ + tagsView: true, + + /** + * 是否固定头部 + */ + fixedHeader: false, + + /** + * 是否显示logo + */ + sidebarLogo: true, + + /** + * 是否显示动态标题 + */ + dynamicTitle: false, + + /** + * @type {string | array} 'production' | ['production', 'development'] + * @description Need show err logs component. + * The default is only used in the production env + * If you want to also use it in dev, you can pass ['production', 'development'] + */ + errorLog: 'production' +} diff --git a/zzyl-ui/src/store/getters.js b/zzyl-ui/src/store/getters.js new file mode 100644 index 0000000..8adb1b6 --- /dev/null +++ b/zzyl-ui/src/store/getters.js @@ -0,0 +1,19 @@ +const getters = { + sidebar: state => state.app.sidebar, + size: state => state.app.size, + device: state => state.app.device, + dict: state => state.dict.dict, + visitedViews: state => state.tagsView.visitedViews, + cachedViews: state => state.tagsView.cachedViews, + token: state => state.user.token, + avatar: state => state.user.avatar, + name: state => state.user.name, + introduction: state => state.user.introduction, + roles: state => state.user.roles, + permissions: state => state.user.permissions, + permission_routes: state => state.permission.routes, + topbarRouters:state => state.permission.topbarRouters, + defaultRoutes:state => state.permission.defaultRoutes, + sidebarRouters:state => state.permission.sidebarRouters, +} +export default getters diff --git a/zzyl-ui/src/store/index.js b/zzyl-ui/src/store/index.js new file mode 100644 index 0000000..97aaef8 --- /dev/null +++ b/zzyl-ui/src/store/index.js @@ -0,0 +1,25 @@ +import Vue from 'vue' +import Vuex from 'vuex' +import app from './modules/app' +import dict from './modules/dict' +import user from './modules/user' +import tagsView from './modules/tagsView' +import permission from './modules/permission' +import settings from './modules/settings' +import getters from './getters' + +Vue.use(Vuex) + +const store = new Vuex.Store({ + modules: { + app, + dict, + user, + tagsView, + permission, + settings + }, + getters +}) + +export default store diff --git a/zzyl-ui/src/store/modules/app.js b/zzyl-ui/src/store/modules/app.js new file mode 100644 index 0000000..3e22d1c --- /dev/null +++ b/zzyl-ui/src/store/modules/app.js @@ -0,0 +1,66 @@ +import Cookies from 'js-cookie' + +const state = { + sidebar: { + opened: Cookies.get('sidebarStatus') ? !!+Cookies.get('sidebarStatus') : true, + withoutAnimation: false, + hide: false + }, + device: 'desktop', + size: Cookies.get('size') || 'medium' +} + +const mutations = { + TOGGLE_SIDEBAR: state => { + if (state.sidebar.hide) { + return false; + } + state.sidebar.opened = !state.sidebar.opened + state.sidebar.withoutAnimation = false + if (state.sidebar.opened) { + Cookies.set('sidebarStatus', 1) + } else { + Cookies.set('sidebarStatus', 0) + } + }, + CLOSE_SIDEBAR: (state, withoutAnimation) => { + Cookies.set('sidebarStatus', 0) + state.sidebar.opened = false + state.sidebar.withoutAnimation = withoutAnimation + }, + TOGGLE_DEVICE: (state, device) => { + state.device = device + }, + SET_SIZE: (state, size) => { + state.size = size + Cookies.set('size', size) + }, + SET_SIDEBAR_HIDE: (state, status) => { + state.sidebar.hide = status + } +} + +const actions = { + toggleSideBar({ commit }) { + commit('TOGGLE_SIDEBAR') + }, + closeSideBar({ commit }, { withoutAnimation }) { + commit('CLOSE_SIDEBAR', withoutAnimation) + }, + toggleDevice({ commit }, device) { + commit('TOGGLE_DEVICE', device) + }, + setSize({ commit }, size) { + commit('SET_SIZE', size) + }, + toggleSideBarHide({ commit }, status) { + commit('SET_SIDEBAR_HIDE', status) + } +} + +export default { + namespaced: true, + state, + mutations, + actions +} diff --git a/zzyl-ui/src/store/modules/dict.js b/zzyl-ui/src/store/modules/dict.js new file mode 100644 index 0000000..7a1b2f0 --- /dev/null +++ b/zzyl-ui/src/store/modules/dict.js @@ -0,0 +1,50 @@ +const state = { + dict: new Array() +} +const mutations = { + SET_DICT: (state, { key, value }) => { + if (key !== null && key !== "") { + state.dict.push({ + key: key, + value: value + }) + } + }, + REMOVE_DICT: (state, key) => { + try { + for (let i = 0; i < state.dict.length; i++) { + if (state.dict[i].key == key) { + state.dict.splice(i, 1) + return true + } + } + } catch (e) { + } + }, + CLEAN_DICT: (state) => { + state.dict = new Array() + } +} + +const actions = { + // 设置字典 + setDict({ commit }, data) { + commit('SET_DICT', data) + }, + // 删除字典 + removeDict({ commit }, key) { + commit('REMOVE_DICT', key) + }, + // 清空字典 + cleanDict({ commit }) { + commit('CLEAN_DICT') + } +} + +export default { + namespaced: true, + state, + mutations, + actions +} + diff --git a/zzyl-ui/src/store/modules/permission.js b/zzyl-ui/src/store/modules/permission.js new file mode 100644 index 0000000..b3c216a --- /dev/null +++ b/zzyl-ui/src/store/modules/permission.js @@ -0,0 +1,137 @@ +import auth from '@/plugins/auth' +import router, { constantRoutes, dynamicRoutes } from '@/router' +import { getRouters } from '@/api/menu' +import Layout from '@/layout/index' +import ParentView from '@/components/ParentView' +import InnerLink from '@/layout/components/InnerLink' + +const permission = { + state: { + routes: [], + addRoutes: [], + defaultRoutes: [], + topbarRouters: [], + sidebarRouters: [] + }, + mutations: { + SET_ROUTES: (state, routes) => { + state.addRoutes = routes + state.routes = constantRoutes.concat(routes) + }, + SET_DEFAULT_ROUTES: (state, routes) => { + state.defaultRoutes = constantRoutes.concat(routes) + }, + SET_TOPBAR_ROUTES: (state, routes) => { + state.topbarRouters = routes + }, + SET_SIDEBAR_ROUTERS: (state, routes) => { + state.sidebarRouters = routes + }, + }, + actions: { + // 生成路由 + GenerateRoutes({ commit }) { + return new Promise(resolve => { + // 向后端请求路由数据 + getRouters().then(res => { + const sdata = JSON.parse(JSON.stringify(res.data)) + const rdata = JSON.parse(JSON.stringify(res.data)) + const sidebarRoutes = filterAsyncRouter(sdata) + const rewriteRoutes = filterAsyncRouter(rdata, false, true) + const asyncRoutes = filterDynamicRoutes(dynamicRoutes); + rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true }) + router.addRoutes(asyncRoutes); + commit('SET_ROUTES', rewriteRoutes) + commit('SET_SIDEBAR_ROUTERS', constantRoutes.concat(sidebarRoutes)) + commit('SET_DEFAULT_ROUTES', sidebarRoutes) + commit('SET_TOPBAR_ROUTES', sidebarRoutes) + resolve(rewriteRoutes) + }) + }) + } + } +} + +// 遍历后台传来的路由字符串,转换为组件对象 +function filterAsyncRouter(asyncRouterMap, lastRouter = false, type = false) { + return asyncRouterMap.filter(route => { + if (type && route.children) { + route.children = filterChildren(route.children) + } + if (route.component) { + // Layout ParentView 组件特殊处理 + if (route.component === 'Layout') { + route.component = Layout + } else if (route.component === 'ParentView') { + route.component = ParentView + } else if (route.component === 'InnerLink') { + route.component = InnerLink + } else { + route.component = loadView(route.component) + } + } + if (route.children != null && route.children && route.children.length) { + route.children = filterAsyncRouter(route.children, route, type) + } else { + delete route['children'] + delete route['redirect'] + } + return true + }) +} + +function filterChildren(childrenMap, lastRouter = false) { + var children = [] + childrenMap.forEach((el, index) => { + if (el.children && el.children.length) { + if (el.component === 'ParentView' && !lastRouter) { + el.children.forEach(c => { + c.path = el.path + '/' + c.path + if (c.children && c.children.length) { + children = children.concat(filterChildren(c.children, c)) + return + } + children.push(c) + }) + return + } + } + if (lastRouter) { + el.path = lastRouter.path + '/' + el.path + if (el.children && el.children.length) { + children = children.concat(filterChildren(el.children, el)) + return + } + } + children = children.concat(el) + }) + return children +} + +// 动态路由遍历,验证是否具备权限 +export function filterDynamicRoutes(routes) { + const res = [] + routes.forEach(route => { + if (route.permissions) { + if (auth.hasPermiOr(route.permissions)) { + res.push(route) + } + } else if (route.roles) { + if (auth.hasRoleOr(route.roles)) { + res.push(route) + } + } + }) + return res +} + +export const loadView = (view) => { + if (process.env.NODE_ENV === 'development') { + return (resolve) => require([`@/views/${view}`], resolve) + } else { + // 使用 import 实现生产环境的路由懒加载 + return () => import(`@/views/${view}`) + } +} + +export default permission diff --git a/zzyl-ui/src/store/modules/settings.js b/zzyl-ui/src/store/modules/settings.js new file mode 100644 index 0000000..2455a1e --- /dev/null +++ b/zzyl-ui/src/store/modules/settings.js @@ -0,0 +1,42 @@ +import defaultSettings from '@/settings' + +const { sideTheme, showSettings, topNav, tagsView, fixedHeader, sidebarLogo, dynamicTitle } = defaultSettings + +const storageSetting = JSON.parse(localStorage.getItem('layout-setting')) || '' +const state = { + title: '', + theme: storageSetting.theme || '#409EFF', + sideTheme: storageSetting.sideTheme || sideTheme, + showSettings: showSettings, + topNav: storageSetting.topNav === undefined ? topNav : storageSetting.topNav, + tagsView: storageSetting.tagsView === undefined ? tagsView : storageSetting.tagsView, + fixedHeader: storageSetting.fixedHeader === undefined ? fixedHeader : storageSetting.fixedHeader, + sidebarLogo: storageSetting.sidebarLogo === undefined ? sidebarLogo : storageSetting.sidebarLogo, + dynamicTitle: storageSetting.dynamicTitle === undefined ? dynamicTitle : storageSetting.dynamicTitle +} +const mutations = { + CHANGE_SETTING: (state, { key, value }) => { + if (state.hasOwnProperty(key)) { + state[key] = value + } + } +} + +const actions = { + // 修改布局设置 + changeSetting({ commit }, data) { + commit('CHANGE_SETTING', data) + }, + // 设置网页标题 + setTitle({ commit }, title) { + state.title = title + } +} + +export default { + namespaced: true, + state, + mutations, + actions +} + diff --git a/zzyl-ui/src/store/modules/tagsView.js b/zzyl-ui/src/store/modules/tagsView.js new file mode 100644 index 0000000..5fc011c --- /dev/null +++ b/zzyl-ui/src/store/modules/tagsView.js @@ -0,0 +1,228 @@ +const state = { + visitedViews: [], + cachedViews: [], + iframeViews: [] +} + +const mutations = { + ADD_IFRAME_VIEW: (state, view) => { + if (state.iframeViews.some(v => v.path === view.path)) return + state.iframeViews.push( + Object.assign({}, view, { + title: view.meta.title || 'no-name' + }) + ) + }, + ADD_VISITED_VIEW: (state, view) => { + if (state.visitedViews.some(v => v.path === view.path)) return + state.visitedViews.push( + Object.assign({}, view, { + title: view.meta.title || 'no-name' + }) + ) + }, + ADD_CACHED_VIEW: (state, view) => { + if (state.cachedViews.includes(view.name)) return + if (view.meta && !view.meta.noCache) { + state.cachedViews.push(view.name) + } + }, + DEL_VISITED_VIEW: (state, view) => { + for (const [i, v] of state.visitedViews.entries()) { + if (v.path === view.path) { + state.visitedViews.splice(i, 1) + break + } + } + state.iframeViews = state.iframeViews.filter(item => item.path !== view.path) + }, + DEL_IFRAME_VIEW: (state, view) => { + state.iframeViews = state.iframeViews.filter(item => item.path !== view.path) + }, + DEL_CACHED_VIEW: (state, view) => { + const index = state.cachedViews.indexOf(view.name) + index > -1 && state.cachedViews.splice(index, 1) + }, + + DEL_OTHERS_VISITED_VIEWS: (state, view) => { + state.visitedViews = state.visitedViews.filter(v => { + return v.meta.affix || v.path === view.path + }) + state.iframeViews = state.iframeViews.filter(item => item.path === view.path) + }, + DEL_OTHERS_CACHED_VIEWS: (state, view) => { + const index = state.cachedViews.indexOf(view.name) + if (index > -1) { + state.cachedViews = state.cachedViews.slice(index, index + 1) + } else { + state.cachedViews = [] + } + }, + DEL_ALL_VISITED_VIEWS: state => { + // keep affix tags + const affixTags = state.visitedViews.filter(tag => tag.meta.affix) + state.visitedViews = affixTags + state.iframeViews = [] + }, + DEL_ALL_CACHED_VIEWS: state => { + state.cachedViews = [] + }, + UPDATE_VISITED_VIEW: (state, view) => { + for (let v of state.visitedViews) { + if (v.path === view.path) { + v = Object.assign(v, view) + break + } + } + }, + DEL_RIGHT_VIEWS: (state, view) => { + const index = state.visitedViews.findIndex(v => v.path === view.path) + if (index === -1) { + return + } + state.visitedViews = state.visitedViews.filter((item, idx) => { + if (idx <= index || (item.meta && item.meta.affix)) { + return true + } + const i = state.cachedViews.indexOf(item.name) + if (i > -1) { + state.cachedViews.splice(i, 1) + } + if(item.meta.link) { + const fi = state.iframeViews.findIndex(v => v.path === item.path) + state.iframeViews.splice(fi, 1) + } + return false + }) + }, + DEL_LEFT_VIEWS: (state, view) => { + const index = state.visitedViews.findIndex(v => v.path === view.path) + if (index === -1) { + return + } + state.visitedViews = state.visitedViews.filter((item, idx) => { + if (idx >= index || (item.meta && item.meta.affix)) { + return true + } + const i = state.cachedViews.indexOf(item.name) + if (i > -1) { + state.cachedViews.splice(i, 1) + } + if(item.meta.link) { + const fi = state.iframeViews.findIndex(v => v.path === item.path) + state.iframeViews.splice(fi, 1) + } + return false + }) + } +} + +const actions = { + addView({ dispatch }, view) { + dispatch('addVisitedView', view) + dispatch('addCachedView', view) + }, + addIframeView({ commit }, view) { + commit('ADD_IFRAME_VIEW', view) + }, + addVisitedView({ commit }, view) { + commit('ADD_VISITED_VIEW', view) + }, + addCachedView({ commit }, view) { + commit('ADD_CACHED_VIEW', view) + }, + delView({ dispatch, state }, view) { + return new Promise(resolve => { + dispatch('delVisitedView', view) + dispatch('delCachedView', view) + resolve({ + visitedViews: [...state.visitedViews], + cachedViews: [...state.cachedViews] + }) + }) + }, + delVisitedView({ commit, state }, view) { + return new Promise(resolve => { + commit('DEL_VISITED_VIEW', view) + resolve([...state.visitedViews]) + }) + }, + delIframeView({ commit, state }, view) { + return new Promise(resolve => { + commit('DEL_IFRAME_VIEW', view) + resolve([...state.iframeViews]) + }) + }, + delCachedView({ commit, state }, view) { + return new Promise(resolve => { + commit('DEL_CACHED_VIEW', view) + resolve([...state.cachedViews]) + }) + }, + delOthersViews({ dispatch, state }, view) { + return new Promise(resolve => { + dispatch('delOthersVisitedViews', view) + dispatch('delOthersCachedViews', view) + resolve({ + visitedViews: [...state.visitedViews], + cachedViews: [...state.cachedViews] + }) + }) + }, + delOthersVisitedViews({ commit, state }, view) { + return new Promise(resolve => { + commit('DEL_OTHERS_VISITED_VIEWS', view) + resolve([...state.visitedViews]) + }) + }, + delOthersCachedViews({ commit, state }, view) { + return new Promise(resolve => { + commit('DEL_OTHERS_CACHED_VIEWS', view) + resolve([...state.cachedViews]) + }) + }, + delAllViews({ dispatch, state }, view) { + return new Promise(resolve => { + dispatch('delAllVisitedViews', view) + dispatch('delAllCachedViews', view) + resolve({ + visitedViews: [...state.visitedViews], + cachedViews: [...state.cachedViews] + }) + }) + }, + delAllVisitedViews({ commit, state }) { + return new Promise(resolve => { + commit('DEL_ALL_VISITED_VIEWS') + resolve([...state.visitedViews]) + }) + }, + delAllCachedViews({ commit, state }) { + return new Promise(resolve => { + commit('DEL_ALL_CACHED_VIEWS') + resolve([...state.cachedViews]) + }) + }, + updateVisitedView({ commit }, view) { + commit('UPDATE_VISITED_VIEW', view) + }, + delRightTags({ commit }, view) { + return new Promise(resolve => { + commit('DEL_RIGHT_VIEWS', view) + resolve([...state.visitedViews]) + }) + }, + delLeftTags({ commit }, view) { + return new Promise(resolve => { + commit('DEL_LEFT_VIEWS', view) + resolve([...state.visitedViews]) + }) + }, +} + +export default { + namespaced: true, + state, + mutations, + actions +} diff --git a/zzyl-ui/src/store/modules/user.js b/zzyl-ui/src/store/modules/user.js new file mode 100644 index 0000000..cdbab1e --- /dev/null +++ b/zzyl-ui/src/store/modules/user.js @@ -0,0 +1,101 @@ +import { login, logout, getInfo } from '@/api/login' +import { getToken, setToken, removeToken } from '@/utils/auth' + +const user = { + state: { + token: getToken(), + id: '', + name: '', + avatar: '', + roles: [], + permissions: [] + }, + + mutations: { + SET_TOKEN: (state, token) => { + state.token = token + }, + SET_ID: (state, id) => { + state.id = id + }, + SET_NAME: (state, name) => { + state.name = name + }, + SET_AVATAR: (state, avatar) => { + state.avatar = avatar + }, + SET_ROLES: (state, roles) => { + state.roles = roles + }, + SET_PERMISSIONS: (state, permissions) => { + state.permissions = permissions + } + }, + + actions: { + // 登录 + Login({ commit }, userInfo) { + const username = userInfo.username.trim() + const password = userInfo.password + const code = userInfo.code + const uuid = userInfo.uuid + return new Promise((resolve, reject) => { + login(username, password, code, uuid).then(res => { + setToken(res.token) + commit('SET_TOKEN', res.token) + resolve() + }).catch(error => { + reject(error) + }) + }) + }, + + // 获取用户信息 + GetInfo({ commit, state }) { + return new Promise((resolve, reject) => { + getInfo().then(res => { + const user = res.user + const avatar = (user.avatar == "" || user.avatar == null) ? require("@/assets/images/profile.jpg") : process.env.VUE_APP_BASE_API + user.avatar; + if (res.roles && res.roles.length > 0) { // 验证返回的roles是否是一个非空数组 + commit('SET_ROLES', res.roles) + commit('SET_PERMISSIONS', res.permissions) + } else { + commit('SET_ROLES', ['ROLE_DEFAULT']) + } + commit('SET_ID', user.userId) + commit('SET_NAME', user.userName) + commit('SET_AVATAR', avatar) + resolve(res) + }).catch(error => { + reject(error) + }) + }) + }, + + // 退出系统 + LogOut({ commit, state }) { + return new Promise((resolve, reject) => { + logout(state.token).then(() => { + commit('SET_TOKEN', '') + commit('SET_ROLES', []) + commit('SET_PERMISSIONS', []) + removeToken() + resolve() + }).catch(error => { + reject(error) + }) + }) + }, + + // 前端 登出 + FedLogOut({ commit }) { + return new Promise(resolve => { + commit('SET_TOKEN', '') + removeToken() + resolve() + }) + } + } +} + +export default user diff --git a/zzyl-ui/src/utils/auth.js b/zzyl-ui/src/utils/auth.js new file mode 100644 index 0000000..08a43d6 --- /dev/null +++ b/zzyl-ui/src/utils/auth.js @@ -0,0 +1,15 @@ +import Cookies from 'js-cookie' + +const TokenKey = 'Admin-Token' + +export function getToken() { + return Cookies.get(TokenKey) +} + +export function setToken(token) { + return Cookies.set(TokenKey, token) +} + +export function removeToken() { + return Cookies.remove(TokenKey) +} diff --git a/zzyl-ui/src/utils/dict/Dict.js b/zzyl-ui/src/utils/dict/Dict.js new file mode 100644 index 0000000..104bd6e --- /dev/null +++ b/zzyl-ui/src/utils/dict/Dict.js @@ -0,0 +1,82 @@ +import Vue from 'vue' +import { mergeRecursive } from "@/utils/ruoyi"; +import DictMeta from './DictMeta' +import DictData from './DictData' + +const DEFAULT_DICT_OPTIONS = { + types: [], +} + +/** + * @classdesc 字典 + * @property {Object} label 标签对象,内部属性名为字典类型名称 + * @property {Object} dict 字段数组,内部属性名为字典类型名称 + * @property {Array.} _dictMetas 字典元数据数组 + */ +export default class Dict { + constructor() { + this.owner = null + this.label = {} + this.type = {} + } + + init(options) { + if (options instanceof Array) { + options = { types: options } + } + const opts = mergeRecursive(DEFAULT_DICT_OPTIONS, options) + if (opts.types === undefined) { + throw new Error('need dict types') + } + const ps = [] + this._dictMetas = opts.types.map(t => DictMeta.parse(t)) + this._dictMetas.forEach(dictMeta => { + const type = dictMeta.type + Vue.set(this.label, type, {}) + Vue.set(this.type, type, []) + if (dictMeta.lazy) { + return + } + ps.push(loadDict(this, dictMeta)) + }) + return Promise.all(ps) + } + + /** + * 重新加载字典 + * @param {String} type 字典类型 + */ + reloadDict(type) { + const dictMeta = this._dictMetas.find(e => e.type === type) + if (dictMeta === undefined) { + return Promise.reject(`the dict meta of ${type} was not found`) + } + return loadDict(this, dictMeta) + } +} + +/** + * 加载字典 + * @param {Dict} dict 字典 + * @param {DictMeta} dictMeta 字典元数据 + * @returns {Promise} + */ +function loadDict(dict, dictMeta) { + return dictMeta.request(dictMeta) + .then(response => { + const type = dictMeta.type + let dicts = dictMeta.responseConverter(response, dictMeta) + if (!(dicts instanceof Array)) { + console.error('the return of responseConverter must be Array.') + dicts = [] + } else if (dicts.filter(d => d instanceof DictData).length !== dicts.length) { + console.error('the type of elements in dicts must be DictData') + dicts = [] + } + dict.type[type].splice(0, Number.MAX_SAFE_INTEGER, ...dicts) + dicts.forEach(d => { + Vue.set(dict.label[type], d.value, d.label) + }) + return dicts + }) +} diff --git a/zzyl-ui/src/utils/dict/DictConverter.js b/zzyl-ui/src/utils/dict/DictConverter.js new file mode 100644 index 0000000..0cf5df8 --- /dev/null +++ b/zzyl-ui/src/utils/dict/DictConverter.js @@ -0,0 +1,17 @@ +import DictOptions from './DictOptions' +import DictData from './DictData' + +export default function(dict, dictMeta) { + const label = determineDictField(dict, dictMeta.labelField, ...DictOptions.DEFAULT_LABEL_FIELDS) + const value = determineDictField(dict, dictMeta.valueField, ...DictOptions.DEFAULT_VALUE_FIELDS) + return new DictData(dict[label], dict[value], dict) +} + +/** + * 确定字典字段 + * @param {DictData} dict + * @param {...String} fields + */ +function determineDictField(dict, ...fields) { + return fields.find(f => Object.prototype.hasOwnProperty.call(dict, f)) +} diff --git a/zzyl-ui/src/utils/dict/DictData.js b/zzyl-ui/src/utils/dict/DictData.js new file mode 100644 index 0000000..afc763e --- /dev/null +++ b/zzyl-ui/src/utils/dict/DictData.js @@ -0,0 +1,13 @@ +/** + * @classdesc 字典数据 + * @property {String} label 标签 + * @property {*} value 标签 + * @property {Object} raw 原始数据 + */ +export default class DictData { + constructor(label, value, raw) { + this.label = label + this.value = value + this.raw = raw + } +} diff --git a/zzyl-ui/src/utils/dict/DictMeta.js b/zzyl-ui/src/utils/dict/DictMeta.js new file mode 100644 index 0000000..9779daa --- /dev/null +++ b/zzyl-ui/src/utils/dict/DictMeta.js @@ -0,0 +1,38 @@ +import { mergeRecursive } from "@/utils/ruoyi"; +import DictOptions from './DictOptions' + +/** + * @classdesc 字典元数据 + * @property {String} type 类型 + * @property {Function} request 请求 + * @property {String} label 标签字段 + * @property {String} value 值字段 + */ +export default class DictMeta { + constructor(options) { + this.type = options.type + this.request = options.request + this.responseConverter = options.responseConverter + this.labelField = options.labelField + this.valueField = options.valueField + this.lazy = options.lazy === true + } +} + + +/** + * 解析字典元数据 + * @param {Object} options + * @returns {DictMeta} + */ +DictMeta.parse= function(options) { + let opts = null + if (typeof options === 'string') { + opts = DictOptions.metas[options] || {} + opts.type = options + } else if (typeof options === 'object') { + opts = options + } + opts = mergeRecursive(DictOptions.metas['*'], opts) + return new DictMeta(opts) +} diff --git a/zzyl-ui/src/utils/dict/DictOptions.js b/zzyl-ui/src/utils/dict/DictOptions.js new file mode 100644 index 0000000..338a94e --- /dev/null +++ b/zzyl-ui/src/utils/dict/DictOptions.js @@ -0,0 +1,51 @@ +import { mergeRecursive } from "@/utils/ruoyi"; +import dictConverter from './DictConverter' + +export const options = { + metas: { + '*': { + /** + * 字典请求,方法签名为function(dictMeta: DictMeta): Promise + */ + request: (dictMeta) => { + console.log(`load dict ${dictMeta.type}`) + return Promise.resolve([]) + }, + /** + * 字典响应数据转换器,方法签名为function(response: Object, dictMeta: DictMeta): DictData + */ + responseConverter, + labelField: 'label', + valueField: 'value', + }, + }, + /** + * 默认标签字段 + */ + DEFAULT_LABEL_FIELDS: ['label', 'name', 'title'], + /** + * 默认值字段 + */ + DEFAULT_VALUE_FIELDS: ['value', 'id', 'uid', 'key'], +} + +/** + * 映射字典 + * @param {Object} response 字典数据 + * @param {DictMeta} dictMeta 字典元数据 + * @returns {DictData} + */ +function responseConverter(response, dictMeta) { + const dicts = response.content instanceof Array ? response.content : response + if (dicts === undefined) { + console.warn(`no dict data of "${dictMeta.type}" found in the response`) + return [] + } + return dicts.map(d => dictConverter(d, dictMeta)) +} + +export function mergeOptions(src) { + mergeRecursive(options, src) +} + +export default options diff --git a/zzyl-ui/src/utils/dict/index.js b/zzyl-ui/src/utils/dict/index.js new file mode 100644 index 0000000..215eb9e --- /dev/null +++ b/zzyl-ui/src/utils/dict/index.js @@ -0,0 +1,33 @@ +import Dict from './Dict' +import { mergeOptions } from './DictOptions' + +export default function(Vue, options) { + mergeOptions(options) + Vue.mixin({ + data() { + if (this.$options === undefined || this.$options.dicts === undefined || this.$options.dicts === null) { + return {} + } + const dict = new Dict() + dict.owner = this + return { + dict + } + }, + created() { + if (!(this.dict instanceof Dict)) { + return + } + options.onCreated && options.onCreated(this.dict) + this.dict.init(this.$options.dicts).then(() => { + options.onReady && options.onReady(this.dict) + this.$nextTick(() => { + this.$emit('dictReady', this.dict) + if (this.$options.methods && this.$options.methods.onDictReady instanceof Function) { + this.$options.methods.onDictReady.call(this, this.dict) + } + }) + }) + }, + }) +} diff --git a/zzyl-ui/src/utils/errorCode.js b/zzyl-ui/src/utils/errorCode.js new file mode 100644 index 0000000..d2111ee --- /dev/null +++ b/zzyl-ui/src/utils/errorCode.js @@ -0,0 +1,6 @@ +export default { + '401': '认证失败,无法访问系统资源', + '403': '当前操作没有权限', + '404': '访问资源不存在', + 'default': '系统未知错误,请反馈给管理员' +} diff --git a/zzyl-ui/src/utils/generator/config.js b/zzyl-ui/src/utils/generator/config.js new file mode 100644 index 0000000..7abf227 --- /dev/null +++ b/zzyl-ui/src/utils/generator/config.js @@ -0,0 +1,438 @@ +export const formConf = { + formRef: 'elForm', + formModel: 'formData', + size: 'medium', + labelPosition: 'right', + labelWidth: 100, + formRules: 'rules', + gutter: 15, + disabled: false, + span: 24, + formBtns: true +} + +export const inputComponents = [ + { + label: '单行文本', + tag: 'el-input', + tagIcon: 'input', + placeholder: '请输入', + defaultValue: undefined, + span: 24, + labelWidth: null, + style: { width: '100%' }, + clearable: true, + prepend: '', + append: '', + 'prefix-icon': '', + 'suffix-icon': '', + maxlength: null, + 'show-word-limit': false, + readonly: false, + disabled: false, + required: true, + regList: [], + changeTag: true, + document: 'https://element.eleme.cn/#/zh-CN/component/input' + }, + { + label: '多行文本', + tag: 'el-input', + tagIcon: 'textarea', + type: 'textarea', + placeholder: '请输入', + defaultValue: undefined, + span: 24, + labelWidth: null, + autosize: { + minRows: 4, + maxRows: 4 + }, + style: { width: '100%' }, + maxlength: null, + 'show-word-limit': false, + readonly: false, + disabled: false, + required: true, + regList: [], + changeTag: true, + document: 'https://element.eleme.cn/#/zh-CN/component/input' + }, + { + label: '密码', + tag: 'el-input', + tagIcon: 'password', + placeholder: '请输入', + defaultValue: undefined, + span: 24, + 'show-password': true, + labelWidth: null, + style: { width: '100%' }, + clearable: true, + prepend: '', + append: '', + 'prefix-icon': '', + 'suffix-icon': '', + maxlength: null, + 'show-word-limit': false, + readonly: false, + disabled: false, + required: true, + regList: [], + changeTag: true, + document: 'https://element.eleme.cn/#/zh-CN/component/input' + }, + { + label: '计数器', + tag: 'el-input-number', + tagIcon: 'number', + placeholder: '', + defaultValue: undefined, + span: 24, + labelWidth: null, + min: undefined, + max: undefined, + step: undefined, + 'step-strictly': false, + precision: undefined, + 'controls-position': '', + disabled: false, + required: true, + regList: [], + changeTag: true, + document: 'https://element.eleme.cn/#/zh-CN/component/input-number' + } +] + +export const selectComponents = [ + { + label: '下拉选择', + tag: 'el-select', + tagIcon: 'select', + placeholder: '请选择', + defaultValue: undefined, + span: 24, + labelWidth: null, + style: { width: '100%' }, + clearable: true, + disabled: false, + required: true, + filterable: false, + multiple: false, + options: [{ + label: '选项一', + value: 1 + }, { + label: '选项二', + value: 2 + }], + regList: [], + changeTag: true, + document: 'https://element.eleme.cn/#/zh-CN/component/select' + }, + { + label: '级联选择', + tag: 'el-cascader', + tagIcon: 'cascader', + placeholder: '请选择', + defaultValue: [], + span: 24, + labelWidth: null, + style: { width: '100%' }, + props: { + props: { + multiple: false + } + }, + 'show-all-levels': true, + disabled: false, + clearable: true, + filterable: false, + required: true, + options: [{ + id: 1, + value: 1, + label: '选项1', + children: [{ + id: 2, + value: 2, + label: '选项1-1' + }] + }], + dataType: 'dynamic', + labelKey: 'label', + valueKey: 'value', + childrenKey: 'children', + separator: '/', + regList: [], + changeTag: true, + document: 'https://element.eleme.cn/#/zh-CN/component/cascader' + }, + { + label: '单选框组', + tag: 'el-radio-group', + tagIcon: 'radio', + defaultValue: undefined, + span: 24, + labelWidth: null, + style: {}, + optionType: 'default', + border: false, + size: 'medium', + disabled: false, + required: true, + options: [{ + label: '选项一', + value: 1 + }, { + label: '选项二', + value: 2 + }], + regList: [], + changeTag: true, + document: 'https://element.eleme.cn/#/zh-CN/component/radio' + }, + { + label: '多选框组', + tag: 'el-checkbox-group', + tagIcon: 'checkbox', + defaultValue: [], + span: 24, + labelWidth: null, + style: {}, + optionType: 'default', + border: false, + size: 'medium', + disabled: false, + required: true, + options: [{ + label: '选项一', + value: 1 + }, { + label: '选项二', + value: 2 + }], + regList: [], + changeTag: true, + document: 'https://element.eleme.cn/#/zh-CN/component/checkbox' + }, + { + label: '开关', + tag: 'el-switch', + tagIcon: 'switch', + defaultValue: false, + span: 24, + labelWidth: null, + style: {}, + disabled: false, + required: true, + 'active-text': '', + 'inactive-text': '', + 'active-color': null, + 'inactive-color': null, + 'active-value': true, + 'inactive-value': false, + regList: [], + changeTag: true, + document: 'https://element.eleme.cn/#/zh-CN/component/switch' + }, + { + label: '滑块', + tag: 'el-slider', + tagIcon: 'slider', + defaultValue: null, + span: 24, + labelWidth: null, + disabled: false, + required: true, + min: 0, + max: 100, + step: 1, + 'show-stops': false, + range: false, + regList: [], + changeTag: true, + document: 'https://element.eleme.cn/#/zh-CN/component/slider' + }, + { + label: '时间选择', + tag: 'el-time-picker', + tagIcon: 'time', + placeholder: '请选择', + defaultValue: null, + span: 24, + labelWidth: null, + style: { width: '100%' }, + disabled: false, + clearable: true, + required: true, + 'picker-options': { + selectableRange: '00:00:00-23:59:59' + }, + format: 'HH:mm:ss', + 'value-format': 'HH:mm:ss', + regList: [], + changeTag: true, + document: 'https://element.eleme.cn/#/zh-CN/component/time-picker' + }, + { + label: '时间范围', + tag: 'el-time-picker', + tagIcon: 'time-range', + defaultValue: null, + span: 24, + labelWidth: null, + style: { width: '100%' }, + disabled: false, + clearable: true, + required: true, + 'is-range': true, + 'range-separator': '至', + 'start-placeholder': '开始时间', + 'end-placeholder': '结束时间', + format: 'HH:mm:ss', + 'value-format': 'HH:mm:ss', + regList: [], + changeTag: true, + document: 'https://element.eleme.cn/#/zh-CN/component/time-picker' + }, + { + label: '日期选择', + tag: 'el-date-picker', + tagIcon: 'date', + placeholder: '请选择', + defaultValue: null, + type: 'date', + span: 24, + labelWidth: null, + style: { width: '100%' }, + disabled: false, + clearable: true, + required: true, + format: 'yyyy-MM-dd', + 'value-format': 'yyyy-MM-dd', + readonly: false, + regList: [], + changeTag: true, + document: 'https://element.eleme.cn/#/zh-CN/component/date-picker' + }, + { + label: '日期范围', + tag: 'el-date-picker', + tagIcon: 'date-range', + defaultValue: null, + span: 24, + labelWidth: null, + style: { width: '100%' }, + type: 'daterange', + 'range-separator': '至', + 'start-placeholder': '开始日期', + 'end-placeholder': '结束日期', + disabled: false, + clearable: true, + required: true, + format: 'yyyy-MM-dd', + 'value-format': 'yyyy-MM-dd', + readonly: false, + regList: [], + changeTag: true, + document: 'https://element.eleme.cn/#/zh-CN/component/date-picker' + }, + { + label: '评分', + tag: 'el-rate', + tagIcon: 'rate', + defaultValue: 0, + span: 24, + labelWidth: null, + style: {}, + max: 5, + 'allow-half': false, + 'show-text': false, + 'show-score': false, + disabled: false, + required: true, + regList: [], + changeTag: true, + document: 'https://element.eleme.cn/#/zh-CN/component/rate' + }, + { + label: '颜色选择', + tag: 'el-color-picker', + tagIcon: 'color', + defaultValue: null, + labelWidth: null, + 'show-alpha': false, + 'color-format': '', + disabled: false, + required: true, + size: 'medium', + regList: [], + changeTag: true, + document: 'https://element.eleme.cn/#/zh-CN/component/color-picker' + }, + { + label: '上传', + tag: 'el-upload', + tagIcon: 'upload', + action: 'https://jsonplaceholder.typicode.com/posts/', + defaultValue: null, + labelWidth: null, + disabled: false, + required: true, + accept: '', + name: 'file', + 'auto-upload': true, + showTip: false, + buttonText: '点击上传', + fileSize: 2, + sizeUnit: 'MB', + 'list-type': 'text', + multiple: false, + regList: [], + changeTag: true, + document: 'https://element.eleme.cn/#/zh-CN/component/upload' + } +] + +export const layoutComponents = [ + { + layout: 'rowFormItem', + tagIcon: 'row', + type: 'default', + justify: 'start', + align: 'top', + label: '行容器', + layoutTree: true, + children: [], + document: 'https://element.eleme.cn/#/zh-CN/component/layout' + }, + { + layout: 'colFormItem', + label: '按钮', + changeTag: true, + labelWidth: null, + tag: 'el-button', + tagIcon: 'button', + span: 24, + default: '主要按钮', + type: 'primary', + icon: 'el-icon-search', + size: 'medium', + disabled: false, + document: 'https://element.eleme.cn/#/zh-CN/component/button' + } +] + +// 组件rule的触发方式,无触发方式的组件不生成rule +export const trigger = { + 'el-input': 'blur', + 'el-input-number': 'blur', + 'el-select': 'change', + 'el-radio-group': 'change', + 'el-checkbox-group': 'change', + 'el-cascader': 'change', + 'el-time-picker': 'change', + 'el-date-picker': 'change', + 'el-rate': 'change' +} diff --git a/zzyl-ui/src/utils/generator/css.js b/zzyl-ui/src/utils/generator/css.js new file mode 100644 index 0000000..c1c62e6 --- /dev/null +++ b/zzyl-ui/src/utils/generator/css.js @@ -0,0 +1,18 @@ +const styles = { + 'el-rate': '.el-rate{display: inline-block; vertical-align: text-top;}', + 'el-upload': '.el-upload__tip{line-height: 1.2;}' +} + +function addCss(cssList, el) { + const css = styles[el.tag] + css && cssList.indexOf(css) === -1 && cssList.push(css) + if (el.children) { + el.children.forEach(el2 => addCss(cssList, el2)) + } +} + +export function makeUpCss(conf) { + const cssList = [] + conf.fields.forEach(el => addCss(cssList, el)) + return cssList.join('\n') +} diff --git a/zzyl-ui/src/utils/generator/drawingDefault.js b/zzyl-ui/src/utils/generator/drawingDefault.js new file mode 100644 index 0000000..09f133c --- /dev/null +++ b/zzyl-ui/src/utils/generator/drawingDefault.js @@ -0,0 +1,29 @@ +export default [ + { + layout: 'colFormItem', + tagIcon: 'input', + label: '手机号', + vModel: 'mobile', + formId: 6, + tag: 'el-input', + placeholder: '请输入手机号', + defaultValue: '', + span: 24, + style: { width: '100%' }, + clearable: true, + prepend: '', + append: '', + 'prefix-icon': 'el-icon-mobile', + 'suffix-icon': '', + maxlength: 11, + 'show-word-limit': true, + readonly: false, + disabled: false, + required: true, + changeTag: true, + regList: [{ + pattern: '/^1(3|4|5|7|8|9)\\d{9}$/', + message: '手机号格式错误' + }] + } +] diff --git a/zzyl-ui/src/utils/generator/html.js b/zzyl-ui/src/utils/generator/html.js new file mode 100644 index 0000000..9bcc536 --- /dev/null +++ b/zzyl-ui/src/utils/generator/html.js @@ -0,0 +1,359 @@ +/* eslint-disable max-len */ +import { trigger } from './config' + +let confGlobal +let someSpanIsNot24 + +export function dialogWrapper(str) { + return ` + ${str} +
+ 取消 + 确定 +
+
` +} + +export function vueTemplate(str) { + return `` +} + +export function vueScript(str) { + return `` +} + +export function cssStyle(cssStr) { + return `` +} + +function buildFormTemplate(conf, child, type) { + let labelPosition = '' + if (conf.labelPosition !== 'right') { + labelPosition = `label-position="${conf.labelPosition}"` + } + const disabled = conf.disabled ? `:disabled="${conf.disabled}"` : '' + let str = ` + ${child} + ${buildFromBtns(conf, type)} + ` + if (someSpanIsNot24) { + str = ` + ${str} + ` + } + return str +} + +function buildFromBtns(conf, type) { + let str = '' + if (conf.formBtns && type === 'file') { + str = ` + 提交 + 重置 + ` + if (someSpanIsNot24) { + str = ` + ${str} + ` + } + } + return str +} + +// span不为24的用el-col包裹 +function colWrapper(element, str) { + if (someSpanIsNot24 || element.span !== 24) { + return ` + ${str} + ` + } + return str +} + +const layouts = { + colFormItem(element) { + let labelWidth = '' + if (element.labelWidth && element.labelWidth !== confGlobal.labelWidth) { + labelWidth = `label-width="${element.labelWidth}px"` + } + const required = !trigger[element.tag] && element.required ? 'required' : '' + const tagDom = tags[element.tag] ? tags[element.tag](element) : null + let str = ` + ${tagDom} + ` + str = colWrapper(element, str) + return str + }, + rowFormItem(element) { + const type = element.type === 'default' ? '' : `type="${element.type}"` + const justify = element.type === 'default' ? '' : `justify="${element.justify}"` + const align = element.type === 'default' ? '' : `align="${element.align}"` + const gutter = element.gutter ? `gutter="${element.gutter}"` : '' + const children = element.children.map(el => layouts[el.layout](el)) + let str = ` + ${children.join('\n')} + ` + str = colWrapper(element, str) + return str + } +} + +const tags = { + 'el-button': el => { + const { + tag, disabled + } = attrBuilder(el) + const type = el.type ? `type="${el.type}"` : '' + const icon = el.icon ? `icon="${el.icon}"` : '' + const size = el.size ? `size="${el.size}"` : '' + let child = buildElButtonChild(el) + + if (child) child = `\n${child}\n` // 换行 + return `<${el.tag} ${type} ${icon} ${size} ${disabled}>${child}` + }, + 'el-input': el => { + const { + disabled, vModel, clearable, placeholder, width + } = attrBuilder(el) + const maxlength = el.maxlength ? `:maxlength="${el.maxlength}"` : '' + const showWordLimit = el['show-word-limit'] ? 'show-word-limit' : '' + const readonly = el.readonly ? 'readonly' : '' + const prefixIcon = el['prefix-icon'] ? `prefix-icon='${el['prefix-icon']}'` : '' + const suffixIcon = el['suffix-icon'] ? `suffix-icon='${el['suffix-icon']}'` : '' + const showPassword = el['show-password'] ? 'show-password' : '' + const type = el.type ? `type="${el.type}"` : '' + const autosize = el.autosize && el.autosize.minRows + ? `:autosize="{minRows: ${el.autosize.minRows}, maxRows: ${el.autosize.maxRows}}"` + : '' + let child = buildElInputChild(el) + + if (child) child = `\n${child}\n` // 换行 + return `<${el.tag} ${vModel} ${type} ${placeholder} ${maxlength} ${showWordLimit} ${readonly} ${disabled} ${clearable} ${prefixIcon} ${suffixIcon} ${showPassword} ${autosize} ${width}>${child}` + }, + 'el-input-number': el => { + const { disabled, vModel, placeholder } = attrBuilder(el) + const controlsPosition = el['controls-position'] ? `controls-position=${el['controls-position']}` : '' + const min = el.min ? `:min='${el.min}'` : '' + const max = el.max ? `:max='${el.max}'` : '' + const step = el.step ? `:step='${el.step}'` : '' + const stepStrictly = el['step-strictly'] ? 'step-strictly' : '' + const precision = el.precision ? `:precision='${el.precision}'` : '' + + return `<${el.tag} ${vModel} ${placeholder} ${step} ${stepStrictly} ${precision} ${controlsPosition} ${min} ${max} ${disabled}>` + }, + 'el-select': el => { + const { + disabled, vModel, clearable, placeholder, width + } = attrBuilder(el) + const filterable = el.filterable ? 'filterable' : '' + const multiple = el.multiple ? 'multiple' : '' + let child = buildElSelectChild(el) + + if (child) child = `\n${child}\n` // 换行 + return `<${el.tag} ${vModel} ${placeholder} ${disabled} ${multiple} ${filterable} ${clearable} ${width}>${child}` + }, + 'el-radio-group': el => { + const { disabled, vModel } = attrBuilder(el) + const size = `size="${el.size}"` + let child = buildElRadioGroupChild(el) + + if (child) child = `\n${child}\n` // 换行 + return `<${el.tag} ${vModel} ${size} ${disabled}>${child}` + }, + 'el-checkbox-group': el => { + const { disabled, vModel } = attrBuilder(el) + const size = `size="${el.size}"` + const min = el.min ? `:min="${el.min}"` : '' + const max = el.max ? `:max="${el.max}"` : '' + let child = buildElCheckboxGroupChild(el) + + if (child) child = `\n${child}\n` // 换行 + return `<${el.tag} ${vModel} ${min} ${max} ${size} ${disabled}>${child}` + }, + 'el-switch': el => { + const { disabled, vModel } = attrBuilder(el) + const activeText = el['active-text'] ? `active-text="${el['active-text']}"` : '' + const inactiveText = el['inactive-text'] ? `inactive-text="${el['inactive-text']}"` : '' + const activeColor = el['active-color'] ? `active-color="${el['active-color']}"` : '' + const inactiveColor = el['inactive-color'] ? `inactive-color="${el['inactive-color']}"` : '' + const activeValue = el['active-value'] !== true ? `:active-value='${JSON.stringify(el['active-value'])}'` : '' + const inactiveValue = el['inactive-value'] !== false ? `:inactive-value='${JSON.stringify(el['inactive-value'])}'` : '' + + return `<${el.tag} ${vModel} ${activeText} ${inactiveText} ${activeColor} ${inactiveColor} ${activeValue} ${inactiveValue} ${disabled}>` + }, + 'el-cascader': el => { + const { + disabled, vModel, clearable, placeholder, width + } = attrBuilder(el) + const options = el.options ? `:options="${el.vModel}Options"` : '' + const props = el.props ? `:props="${el.vModel}Props"` : '' + const showAllLevels = el['show-all-levels'] ? '' : ':show-all-levels="false"' + const filterable = el.filterable ? 'filterable' : '' + const separator = el.separator === '/' ? '' : `separator="${el.separator}"` + + return `<${el.tag} ${vModel} ${options} ${props} ${width} ${showAllLevels} ${placeholder} ${separator} ${filterable} ${clearable} ${disabled}>` + }, + 'el-slider': el => { + const { disabled, vModel } = attrBuilder(el) + const min = el.min ? `:min='${el.min}'` : '' + const max = el.max ? `:max='${el.max}'` : '' + const step = el.step ? `:step='${el.step}'` : '' + const range = el.range ? 'range' : '' + const showStops = el['show-stops'] ? `:show-stops="${el['show-stops']}"` : '' + + return `<${el.tag} ${min} ${max} ${step} ${vModel} ${range} ${showStops} ${disabled}>` + }, + 'el-time-picker': el => { + const { + disabled, vModel, clearable, placeholder, width + } = attrBuilder(el) + const startPlaceholder = el['start-placeholder'] ? `start-placeholder="${el['start-placeholder']}"` : '' + const endPlaceholder = el['end-placeholder'] ? `end-placeholder="${el['end-placeholder']}"` : '' + const rangeSeparator = el['range-separator'] ? `range-separator="${el['range-separator']}"` : '' + const isRange = el['is-range'] ? 'is-range' : '' + const format = el.format ? `format="${el.format}"` : '' + const valueFormat = el['value-format'] ? `value-format="${el['value-format']}"` : '' + const pickerOptions = el['picker-options'] ? `:picker-options='${JSON.stringify(el['picker-options'])}'` : '' + + return `<${el.tag} ${vModel} ${isRange} ${format} ${valueFormat} ${pickerOptions} ${width} ${placeholder} ${startPlaceholder} ${endPlaceholder} ${rangeSeparator} ${clearable} ${disabled}>` + }, + 'el-date-picker': el => { + const { + disabled, vModel, clearable, placeholder, width + } = attrBuilder(el) + const startPlaceholder = el['start-placeholder'] ? `start-placeholder="${el['start-placeholder']}"` : '' + const endPlaceholder = el['end-placeholder'] ? `end-placeholder="${el['end-placeholder']}"` : '' + const rangeSeparator = el['range-separator'] ? `range-separator="${el['range-separator']}"` : '' + const format = el.format ? `format="${el.format}"` : '' + const valueFormat = el['value-format'] ? `value-format="${el['value-format']}"` : '' + const type = el.type === 'date' ? '' : `type="${el.type}"` + const readonly = el.readonly ? 'readonly' : '' + + return `<${el.tag} ${type} ${vModel} ${format} ${valueFormat} ${width} ${placeholder} ${startPlaceholder} ${endPlaceholder} ${rangeSeparator} ${clearable} ${readonly} ${disabled}>` + }, + 'el-rate': el => { + const { disabled, vModel } = attrBuilder(el) + const max = el.max ? `:max='${el.max}'` : '' + const allowHalf = el['allow-half'] ? 'allow-half' : '' + const showText = el['show-text'] ? 'show-text' : '' + const showScore = el['show-score'] ? 'show-score' : '' + + return `<${el.tag} ${vModel} ${allowHalf} ${showText} ${showScore} ${disabled}>` + }, + 'el-color-picker': el => { + const { disabled, vModel } = attrBuilder(el) + const size = `size="${el.size}"` + const showAlpha = el['show-alpha'] ? 'show-alpha' : '' + const colorFormat = el['color-format'] ? `color-format="${el['color-format']}"` : '' + + return `<${el.tag} ${vModel} ${size} ${showAlpha} ${colorFormat} ${disabled}>` + }, + 'el-upload': el => { + const disabled = el.disabled ? ':disabled=\'true\'' : '' + const action = el.action ? `:action="${el.vModel}Action"` : '' + const multiple = el.multiple ? 'multiple' : '' + const listType = el['list-type'] !== 'text' ? `list-type="${el['list-type']}"` : '' + const accept = el.accept ? `accept="${el.accept}"` : '' + const name = el.name !== 'file' ? `name="${el.name}"` : '' + const autoUpload = el['auto-upload'] === false ? ':auto-upload="false"' : '' + const beforeUpload = `:before-upload="${el.vModel}BeforeUpload"` + const fileList = `:file-list="${el.vModel}fileList"` + const ref = `ref="${el.vModel}"` + let child = buildElUploadChild(el) + + if (child) child = `\n${child}\n` // 换行 + return `<${el.tag} ${ref} ${fileList} ${action} ${autoUpload} ${multiple} ${beforeUpload} ${listType} ${accept} ${name} ${disabled}>${child}` + } +} + +function attrBuilder(el) { + return { + vModel: `v-model="${confGlobal.formModel}.${el.vModel}"`, + clearable: el.clearable ? 'clearable' : '', + placeholder: el.placeholder ? `placeholder="${el.placeholder}"` : '', + width: el.style && el.style.width ? ':style="{width: \'100%\'}"' : '', + disabled: el.disabled ? ':disabled=\'true\'' : '' + } +} + +// el-buttin 子级 +function buildElButtonChild(conf) { + const children = [] + if (conf.default) { + children.push(conf.default) + } + return children.join('\n') +} + +// el-input innerHTML +function buildElInputChild(conf) { + const children = [] + if (conf.prepend) { + children.push(``) + } + if (conf.append) { + children.push(``) + } + return children.join('\n') +} + +function buildElSelectChild(conf) { + const children = [] + if (conf.options && conf.options.length) { + children.push(``) + } + return children.join('\n') +} + +function buildElRadioGroupChild(conf) { + const children = [] + if (conf.options && conf.options.length) { + const tag = conf.optionType === 'button' ? 'el-radio-button' : 'el-radio' + const border = conf.border ? 'border' : '' + children.push(`<${tag} v-for="(item, index) in ${conf.vModel}Options" :key="index" :label="item.value" :disabled="item.disabled" ${border}>{{item.label}}`) + } + return children.join('\n') +} + +function buildElCheckboxGroupChild(conf) { + const children = [] + if (conf.options && conf.options.length) { + const tag = conf.optionType === 'button' ? 'el-checkbox-button' : 'el-checkbox' + const border = conf.border ? 'border' : '' + children.push(`<${tag} v-for="(item, index) in ${conf.vModel}Options" :key="index" :label="item.value" :disabled="item.disabled" ${border}>{{item.label}}`) + } + return children.join('\n') +} + +function buildElUploadChild(conf) { + const list = [] + if (conf['list-type'] === 'picture-card') list.push('') + else list.push(`${conf.buttonText}`) + if (conf.showTip) list.push(`
只能上传不超过 ${conf.fileSize}${conf.sizeUnit} 的${conf.accept}文件
`) + return list.join('\n') +} + +export function makeUpHtml(conf, type) { + const htmlList = [] + confGlobal = conf + someSpanIsNot24 = conf.fields.some(item => item.span !== 24) + conf.fields.forEach(el => { + htmlList.push(layouts[el.layout](el)) + }) + const htmlStr = htmlList.join('\n') + + let temp = buildFormTemplate(conf, htmlStr, type) + if (type === 'dialog') { + temp = dialogWrapper(temp) + } + confGlobal = null + return temp +} diff --git a/zzyl-ui/src/utils/generator/icon.json b/zzyl-ui/src/utils/generator/icon.json new file mode 100644 index 0000000..2d9999a --- /dev/null +++ b/zzyl-ui/src/utils/generator/icon.json @@ -0,0 +1 @@ +["platform-eleme","eleme","delete-solid","delete","s-tools","setting","user-solid","user","phone","phone-outline","more","more-outline","star-on","star-off","s-goods","goods","warning","warning-outline","question","info","remove","circle-plus","success","error","zoom-in","zoom-out","remove-outline","circle-plus-outline","circle-check","circle-close","s-help","help","minus","plus","check","close","picture","picture-outline","picture-outline-round","upload","upload2","download","camera-solid","camera","video-camera-solid","video-camera","message-solid","bell","s-cooperation","s-order","s-platform","s-fold","s-unfold","s-operation","s-promotion","s-home","s-release","s-ticket","s-management","s-open","s-shop","s-marketing","s-flag","s-comment","s-finance","s-claim","s-custom","s-opportunity","s-data","s-check","s-grid","menu","share","d-caret","caret-left","caret-right","caret-bottom","caret-top","bottom-left","bottom-right","back","right","bottom","top","top-left","top-right","arrow-left","arrow-right","arrow-down","arrow-up","d-arrow-left","d-arrow-right","video-pause","video-play","refresh","refresh-right","refresh-left","finished","sort","sort-up","sort-down","rank","loading","view","c-scale-to-original","date","edit","edit-outline","folder","folder-opened","folder-add","folder-remove","folder-delete","folder-checked","tickets","document-remove","document-delete","document-copy","document-checked","document","document-add","printer","paperclip","takeaway-box","search","monitor","attract","mobile","scissors","umbrella","headset","brush","mouse","coordinate","magic-stick","reading","data-line","data-board","pie-chart","data-analysis","collection-tag","film","suitcase","suitcase-1","receiving","collection","files","notebook-1","notebook-2","toilet-paper","office-building","school","table-lamp","house","no-smoking","smoking","shopping-cart-full","shopping-cart-1","shopping-cart-2","shopping-bag-1","shopping-bag-2","sold-out","sell","present","box","bank-card","money","coin","wallet","discount","price-tag","news","guide","male","female","thumb","cpu","link","connection","open","turn-off","set-up","chat-round","chat-line-round","chat-square","chat-dot-round","chat-dot-square","chat-line-square","message","postcard","position","turn-off-microphone","microphone","close-notification","bangzhu","time","odometer","crop","aim","switch-button","full-screen","copy-document","mic","stopwatch","medal-1","medal","trophy","trophy-1","first-aid-kit","discover","place","location","location-outline","location-information","add-location","delete-location","map-location","alarm-clock","timer","watch-1","watch","lock","unlock","key","service","mobile-phone","bicycle","truck","ship","basketball","football","soccer","baseball","wind-power","light-rain","lightning","heavy-rain","sunrise","sunrise-1","sunset","sunny","cloudy","partly-cloudy","cloudy-and-sunny","moon","moon-night","dish","dish-1","food","chicken","fork-spoon","knife-fork","burger","tableware","sugar","dessert","ice-cream","hot-water","water-cup","coffee-cup","cold-drink","goblet","goblet-full","goblet-square","goblet-square-full","refrigerator","grape","watermelon","cherry","apple","pear","orange","coffee","ice-tea","ice-drink","milk-tea","potato-strips","lollipop","ice-cream-square","ice-cream-round"] \ No newline at end of file diff --git a/zzyl-ui/src/utils/generator/js.js b/zzyl-ui/src/utils/generator/js.js new file mode 100644 index 0000000..ee8668d --- /dev/null +++ b/zzyl-ui/src/utils/generator/js.js @@ -0,0 +1,235 @@ +import { exportDefault, titleCase } from '@/utils/index' +import { trigger } from './config' + +const units = { + KB: '1024', + MB: '1024 / 1024', + GB: '1024 / 1024 / 1024' +} +let confGlobal +const inheritAttrs = { + file: '', + dialog: 'inheritAttrs: false,' +} + + +export function makeUpJs(conf, type) { + confGlobal = conf = JSON.parse(JSON.stringify(conf)) + const dataList = [] + const ruleList = [] + const optionsList = [] + const propsList = [] + const methodList = mixinMethod(type) + const uploadVarList = [] + + conf.fields.forEach(el => { + buildAttributes(el, dataList, ruleList, optionsList, methodList, propsList, uploadVarList) + }) + + const script = buildexport( + conf, + type, + dataList.join('\n'), + ruleList.join('\n'), + optionsList.join('\n'), + uploadVarList.join('\n'), + propsList.join('\n'), + methodList.join('\n') + ) + confGlobal = null + return script +} + +function buildAttributes(el, dataList, ruleList, optionsList, methodList, propsList, uploadVarList) { + buildData(el, dataList) + buildRules(el, ruleList) + + if (el.options && el.options.length) { + buildOptions(el, optionsList) + if (el.dataType === 'dynamic') { + const model = `${el.vModel}Options` + const options = titleCase(model) + buildOptionMethod(`get${options}`, model, methodList) + } + } + + if (el.props && el.props.props) { + buildProps(el, propsList) + } + + if (el.action && el.tag === 'el-upload') { + uploadVarList.push( + `${el.vModel}Action: '${el.action}', + ${el.vModel}fileList: [],` + ) + methodList.push(buildBeforeUpload(el)) + if (!el['auto-upload']) { + methodList.push(buildSubmitUpload(el)) + } + } + + if (el.children) { + el.children.forEach(el2 => { + buildAttributes(el2, dataList, ruleList, optionsList, methodList, propsList, uploadVarList) + }) + } +} + +function mixinMethod(type) { + const list = []; const + minxins = { + file: confGlobal.formBtns ? { + submitForm: `submitForm() { + this.$refs['${confGlobal.formRef}'].validate(valid => { + if(!valid) return + // TODO 提交表单 + }) + },`, + resetForm: `resetForm() { + this.$refs['${confGlobal.formRef}'].resetFields() + },` + } : null, + dialog: { + onOpen: 'onOpen() {},', + onClose: `onClose() { + this.$refs['${confGlobal.formRef}'].resetFields() + },`, + close: `close() { + this.$emit('update:visible', false) + },`, + handleConfirm: `handleConfirm() { + this.$refs['${confGlobal.formRef}'].validate(valid => { + if(!valid) return + this.close() + }) + },` + } + } + + const methods = minxins[type] + if (methods) { + Object.keys(methods).forEach(key => { + list.push(methods[key]) + }) + } + + return list +} + +function buildData(conf, dataList) { + if (conf.vModel === undefined) return + let defaultValue + if (typeof (conf.defaultValue) === 'string' && !conf.multiple) { + defaultValue = `'${conf.defaultValue}'` + } else { + defaultValue = `${JSON.stringify(conf.defaultValue)}` + } + dataList.push(`${conf.vModel}: ${defaultValue},`) +} + +function buildRules(conf, ruleList) { + if (conf.vModel === undefined) return + const rules = [] + if (trigger[conf.tag]) { + if (conf.required) { + const type = Array.isArray(conf.defaultValue) ? 'type: \'array\',' : '' + let message = Array.isArray(conf.defaultValue) ? `请至少选择一个${conf.vModel}` : conf.placeholder + if (message === undefined) message = `${conf.label}不能为空` + rules.push(`{ required: true, ${type} message: '${message}', trigger: '${trigger[conf.tag]}' }`) + } + if (conf.regList && Array.isArray(conf.regList)) { + conf.regList.forEach(item => { + if (item.pattern) { + rules.push(`{ pattern: ${eval(item.pattern)}, message: '${item.message}', trigger: '${trigger[conf.tag]}' }`) + } + }) + } + ruleList.push(`${conf.vModel}: [${rules.join(',')}],`) + } +} + +function buildOptions(conf, optionsList) { + if (conf.vModel === undefined) return + if (conf.dataType === 'dynamic') { conf.options = [] } + const str = `${conf.vModel}Options: ${JSON.stringify(conf.options)},` + optionsList.push(str) +} + +function buildProps(conf, propsList) { + if (conf.dataType === 'dynamic') { + conf.valueKey !== 'value' && (conf.props.props.value = conf.valueKey) + conf.labelKey !== 'label' && (conf.props.props.label = conf.labelKey) + conf.childrenKey !== 'children' && (conf.props.props.children = conf.childrenKey) + } + const str = `${conf.vModel}Props: ${JSON.stringify(conf.props.props)},` + propsList.push(str) +} + +function buildBeforeUpload(conf) { + const unitNum = units[conf.sizeUnit]; let rightSizeCode = ''; let acceptCode = ''; const + returnList = [] + if (conf.fileSize) { + rightSizeCode = `let isRightSize = file.size / ${unitNum} < ${conf.fileSize} + if(!isRightSize){ + this.$message.error('文件大小超过 ${conf.fileSize}${conf.sizeUnit}') + }` + returnList.push('isRightSize') + } + if (conf.accept) { + acceptCode = `let isAccept = new RegExp('${conf.accept}').test(file.type) + if(!isAccept){ + this.$message.error('应该选择${conf.accept}类型的文件') + }` + returnList.push('isAccept') + } + const str = `${conf.vModel}BeforeUpload(file) { + ${rightSizeCode} + ${acceptCode} + return ${returnList.join('&&')} + },` + return returnList.length ? str : '' +} + +function buildSubmitUpload(conf) { + const str = `submitUpload() { + this.$refs['${conf.vModel}'].submit() + },` + return str +} + +function buildOptionMethod(methodName, model, methodList) { + const str = `${methodName}() { + // TODO 发起请求获取数据 + this.${model} + },` + methodList.push(str) +} + +function buildexport(conf, type, data, rules, selectOptions, uploadVar, props, methods) { + const str = `${exportDefault}{ + ${inheritAttrs[type]} + components: {}, + props: [], + data () { + return { + ${conf.formModel}: { + ${data} + }, + ${conf.formRules}: { + ${rules} + }, + ${uploadVar} + ${selectOptions} + ${props} + } + }, + computed: {}, + watch: {}, + created () {}, + mounted () {}, + methods: { + ${methods} + } +}` + return str +} diff --git a/zzyl-ui/src/utils/generator/render.js b/zzyl-ui/src/utils/generator/render.js new file mode 100644 index 0000000..e8640f0 --- /dev/null +++ b/zzyl-ui/src/utils/generator/render.js @@ -0,0 +1,126 @@ +import { makeMap } from '@/utils/index' + +// 参考https://github.com/vuejs/vue/blob/v2.6.10/src/platforms/web/server/util.js +const isAttr = makeMap( + 'accept,accept-charset,accesskey,action,align,alt,async,autocomplete,' + + 'autofocus,autoplay,autosave,bgcolor,border,buffered,challenge,charset,' + + 'checked,cite,class,code,codebase,color,cols,colspan,content,http-equiv,' + + 'name,contenteditable,contextmenu,controls,coords,data,datetime,default,' + + 'defer,dir,dirname,disabled,download,draggable,dropzone,enctype,method,for,' + + 'form,formaction,headers,height,hidden,high,href,hreflang,http-equiv,' + + 'icon,id,ismap,itemprop,keytype,kind,label,lang,language,list,loop,low,' + + 'manifest,max,maxlength,media,method,GET,POST,min,multiple,email,file,' + + 'muted,name,novalidate,open,optimum,pattern,ping,placeholder,poster,' + + 'preload,radiogroup,readonly,rel,required,reversed,rows,rowspan,sandbox,' + + 'scope,scoped,seamless,selected,shape,size,type,text,password,sizes,span,' + + 'spellcheck,src,srcdoc,srclang,srcset,start,step,style,summary,tabindex,' + + 'target,title,type,usemap,value,width,wrap' +) + +function vModel(self, dataObject, defaultValue) { + dataObject.props.value = defaultValue + + dataObject.on.input = val => { + self.$emit('input', val) + } +} + +const componentChild = { + 'el-button': { + default(h, conf, key) { + return conf[key] + }, + }, + 'el-input': { + prepend(h, conf, key) { + return + }, + append(h, conf, key) { + return + } + }, + 'el-select': { + options(h, conf, key) { + const list = [] + conf.options.forEach(item => { + list.push() + }) + return list + } + }, + 'el-radio-group': { + options(h, conf, key) { + const list = [] + conf.options.forEach(item => { + if (conf.optionType === 'button') list.push({item.label}) + else list.push({item.label}) + }) + return list + } + }, + 'el-checkbox-group': { + options(h, conf, key) { + const list = [] + conf.options.forEach(item => { + if (conf.optionType === 'button') { + list.push({item.label}) + } else { + list.push({item.label}) + } + }) + return list + } + }, + 'el-upload': { + 'list-type': (h, conf, key) => { + const list = [] + if (conf['list-type'] === 'picture-card') { + list.push() + } else { + list.push({conf.buttonText}) + } + if (conf.showTip) { + list.push(
只能上传不超过 {conf.fileSize}{conf.sizeUnit} 的{conf.accept}文件
) + } + return list + } + } +} + +export default { + render(h) { + const dataObject = { + attrs: {}, + props: {}, + on: {}, + style: {} + } + const confClone = JSON.parse(JSON.stringify(this.conf)) + const children = [] + + const childObjs = componentChild[confClone.tag] + if (childObjs) { + Object.keys(childObjs).forEach(key => { + const childFunc = childObjs[key] + if (confClone[key]) { + children.push(childFunc(h, confClone, key)) + } + }) + } + + Object.keys(confClone).forEach(key => { + const val = confClone[key] + if (key === 'vModel') { + vModel(this, dataObject, confClone.defaultValue) + } else if (dataObject[key]) { + dataObject[key] = val + } else if (!isAttr(key)) { + dataObject.props[key] = val + } else { + dataObject.attrs[key] = val + } + }) + return h(this.conf.tag, dataObject, children) + }, + props: ['conf'] +} diff --git a/zzyl-ui/src/utils/index.js b/zzyl-ui/src/utils/index.js new file mode 100644 index 0000000..df5db12 --- /dev/null +++ b/zzyl-ui/src/utils/index.js @@ -0,0 +1,390 @@ +import { parseTime } from './ruoyi' + +/** + * 表格时间格式化 + */ +export function formatDate(cellValue) { + if (cellValue == null || cellValue == "") return ""; + var date = new Date(cellValue) + var year = date.getFullYear() + var month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1 + var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate() + var hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours() + var minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes() + var seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds() + return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds +} + +/** + * @param {number} time + * @param {string} option + * @returns {string} + */ +export function formatTime(time, option) { + if (('' + time).length === 10) { + time = parseInt(time) * 1000 + } else { + time = +time + } + const d = new Date(time) + const now = Date.now() + + const diff = (now - d) / 1000 + + if (diff < 30) { + return '刚刚' + } else if (diff < 3600) { + // less 1 hour + return Math.ceil(diff / 60) + '分钟前' + } else if (diff < 3600 * 24) { + return Math.ceil(diff / 3600) + '小时前' + } else if (diff < 3600 * 24 * 2) { + return '1天前' + } + if (option) { + return parseTime(time, option) + } else { + return ( + d.getMonth() + + 1 + + '月' + + d.getDate() + + '日' + + d.getHours() + + '时' + + d.getMinutes() + + '分' + ) + } +} + +/** + * @param {string} url + * @returns {Object} + */ +export function getQueryObject(url) { + url = url == null ? window.location.href : url + const search = url.substring(url.lastIndexOf('?') + 1) + const obj = {} + const reg = /([^?&=]+)=([^?&=]*)/g + search.replace(reg, (rs, $1, $2) => { + const name = decodeURIComponent($1) + let val = decodeURIComponent($2) + val = String(val) + obj[name] = val + return rs + }) + return obj +} + +/** + * @param {string} input value + * @returns {number} output value + */ +export function byteLength(str) { + // returns the byte length of an utf8 string + let s = str.length + for (var i = str.length - 1; i >= 0; i--) { + const code = str.charCodeAt(i) + if (code > 0x7f && code <= 0x7ff) s++ + else if (code > 0x7ff && code <= 0xffff) s += 2 + if (code >= 0xDC00 && code <= 0xDFFF) i-- + } + return s +} + +/** + * @param {Array} actual + * @returns {Array} + */ +export function cleanArray(actual) { + const newArray = [] + for (let i = 0; i < actual.length; i++) { + if (actual[i]) { + newArray.push(actual[i]) + } + } + return newArray +} + +/** + * @param {Object} json + * @returns {Array} + */ +export function param(json) { + if (!json) return '' + return cleanArray( + Object.keys(json).map(key => { + if (json[key] === undefined) return '' + return encodeURIComponent(key) + '=' + encodeURIComponent(json[key]) + }) + ).join('&') +} + +/** + * @param {string} url + * @returns {Object} + */ +export function param2Obj(url) { + const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ') + if (!search) { + return {} + } + const obj = {} + const searchArr = search.split('&') + searchArr.forEach(v => { + const index = v.indexOf('=') + if (index !== -1) { + const name = v.substring(0, index) + const val = v.substring(index + 1, v.length) + obj[name] = val + } + }) + return obj +} + +/** + * @param {string} val + * @returns {string} + */ +export function html2Text(val) { + const div = document.createElement('div') + div.innerHTML = val + return div.textContent || div.innerText +} + +/** + * Merges two objects, giving the last one precedence + * @param {Object} target + * @param {(Object|Array)} source + * @returns {Object} + */ +export function objectMerge(target, source) { + if (typeof target !== 'object') { + target = {} + } + if (Array.isArray(source)) { + return source.slice() + } + Object.keys(source).forEach(property => { + const sourceProperty = source[property] + if (typeof sourceProperty === 'object') { + target[property] = objectMerge(target[property], sourceProperty) + } else { + target[property] = sourceProperty + } + }) + return target +} + +/** + * @param {HTMLElement} element + * @param {string} className + */ +export function toggleClass(element, className) { + if (!element || !className) { + return + } + let classString = element.className + const nameIndex = classString.indexOf(className) + if (nameIndex === -1) { + classString += '' + className + } else { + classString = + classString.substr(0, nameIndex) + + classString.substr(nameIndex + className.length) + } + element.className = classString +} + +/** + * @param {string} type + * @returns {Date} + */ +export function getTime(type) { + if (type === 'start') { + return new Date().getTime() - 3600 * 1000 * 24 * 90 + } else { + return new Date(new Date().toDateString()) + } +} + +/** + * @param {Function} func + * @param {number} wait + * @param {boolean} immediate + * @return {*} + */ +export function debounce(func, wait, immediate) { + let timeout, args, context, timestamp, result + + const later = function() { + // 据上一次触发时间间隔 + const last = +new Date() - timestamp + + // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait + if (last < wait && last > 0) { + timeout = setTimeout(later, wait - last) + } else { + timeout = null + // 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用 + if (!immediate) { + result = func.apply(context, args) + if (!timeout) context = args = null + } + } + } + + return function(...args) { + context = this + timestamp = +new Date() + const callNow = immediate && !timeout + // 如果延时不存在,重新设定延时 + if (!timeout) timeout = setTimeout(later, wait) + if (callNow) { + result = func.apply(context, args) + context = args = null + } + + return result + } +} + +/** + * This is just a simple version of deep copy + * Has a lot of edge cases bug + * If you want to use a perfect deep copy, use lodash's _.cloneDeep + * @param {Object} source + * @returns {Object} + */ +export function deepClone(source) { + if (!source && typeof source !== 'object') { + throw new Error('error arguments', 'deepClone') + } + const targetObj = source.constructor === Array ? [] : {} + Object.keys(source).forEach(keys => { + if (source[keys] && typeof source[keys] === 'object') { + targetObj[keys] = deepClone(source[keys]) + } else { + targetObj[keys] = source[keys] + } + }) + return targetObj +} + +/** + * @param {Array} arr + * @returns {Array} + */ +export function uniqueArr(arr) { + return Array.from(new Set(arr)) +} + +/** + * @returns {string} + */ +export function createUniqueString() { + const timestamp = +new Date() + '' + const randomNum = parseInt((1 + Math.random()) * 65536) + '' + return (+(randomNum + timestamp)).toString(32) +} + +/** + * Check if an element has a class + * @param {HTMLElement} elm + * @param {string} cls + * @returns {boolean} + */ +export function hasClass(ele, cls) { + return !!ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)')) +} + +/** + * Add class to element + * @param {HTMLElement} elm + * @param {string} cls + */ +export function addClass(ele, cls) { + if (!hasClass(ele, cls)) ele.className += ' ' + cls +} + +/** + * Remove class from element + * @param {HTMLElement} elm + * @param {string} cls + */ +export function removeClass(ele, cls) { + if (hasClass(ele, cls)) { + const reg = new RegExp('(\\s|^)' + cls + '(\\s|$)') + ele.className = ele.className.replace(reg, ' ') + } +} + +export function makeMap(str, expectsLowerCase) { + const map = Object.create(null) + const list = str.split(',') + for (let i = 0; i < list.length; i++) { + map[list[i]] = true + } + return expectsLowerCase + ? val => map[val.toLowerCase()] + : val => map[val] +} + +export const exportDefault = 'export default ' + +export const beautifierConf = { + html: { + indent_size: '2', + indent_char: ' ', + max_preserve_newlines: '-1', + preserve_newlines: false, + keep_array_indentation: false, + break_chained_methods: false, + indent_scripts: 'separate', + brace_style: 'end-expand', + space_before_conditional: true, + unescape_strings: false, + jslint_happy: false, + end_with_newline: true, + wrap_line_length: '110', + indent_inner_html: true, + comma_first: false, + e4x: true, + indent_empty_lines: true + }, + js: { + indent_size: '2', + indent_char: ' ', + max_preserve_newlines: '-1', + preserve_newlines: false, + keep_array_indentation: false, + break_chained_methods: false, + indent_scripts: 'normal', + brace_style: 'end-expand', + space_before_conditional: true, + unescape_strings: false, + jslint_happy: true, + end_with_newline: true, + wrap_line_length: '110', + indent_inner_html: true, + comma_first: false, + e4x: true, + indent_empty_lines: true + } +} + +// 首字母大小 +export function titleCase(str) { + return str.replace(/( |^)[a-z]/g, L => L.toUpperCase()) +} + +// 下划转驼峰 +export function camelCase(str) { + return str.replace(/_[a-z]/g, str1 => str1.substr(-1).toUpperCase()) +} + +export function isNumberStr(str) { + return /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(str) +} + diff --git a/zzyl-ui/src/utils/jsencrypt.js b/zzyl-ui/src/utils/jsencrypt.js new file mode 100644 index 0000000..78d9523 --- /dev/null +++ b/zzyl-ui/src/utils/jsencrypt.js @@ -0,0 +1,30 @@ +import JSEncrypt from 'jsencrypt/bin/jsencrypt.min' + +// 密钥对生成 http://web.chacuo.net/netrsakeypair + +const publicKey = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdH\n' + + 'nzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ==' + +const privateKey = 'MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqhHyZfSsYourNxaY\n' + + '7Nt+PrgrxkiA50efORdI5U5lsW79MmFnusUA355oaSXcLhu5xxB38SMSyP2KvuKN\n' + + 'PuH3owIDAQABAkAfoiLyL+Z4lf4Myxk6xUDgLaWGximj20CUf+5BKKnlrK+Ed8gA\n' + + 'kM0HqoTt2UZwA5E2MzS4EI2gjfQhz5X28uqxAiEA3wNFxfrCZlSZHb0gn2zDpWow\n' + + 'cSxQAgiCstxGUoOqlW8CIQDDOerGKH5OmCJ4Z21v+F25WaHYPxCFMvwxpcw99Ecv\n' + + 'DQIgIdhDTIqD2jfYjPTY8Jj3EDGPbH2HHuffvflECt3Ek60CIQCFRlCkHpi7hthh\n' + + 'YhovyloRYsM+IS9h/0BzlEAuO0ktMQIgSPT3aFAgJYwKpqRYKlLDVcflZFCKY7u3\n' + + 'UP8iWi1Qw0Y=' + +// 加密 +export function encrypt(txt) { + const encryptor = new JSEncrypt() + encryptor.setPublicKey(publicKey) // 设置公钥 + return encryptor.encrypt(txt) // 对数据进行加密 +} + +// 解密 +export function decrypt(txt) { + const encryptor = new JSEncrypt() + encryptor.setPrivateKey(privateKey) // 设置私钥 + return encryptor.decrypt(txt) // 对数据进行解密 +} + diff --git a/zzyl-ui/src/utils/permission.js b/zzyl-ui/src/utils/permission.js new file mode 100644 index 0000000..189a716 --- /dev/null +++ b/zzyl-ui/src/utils/permission.js @@ -0,0 +1,47 @@ +import store from '@/store' + +/** + * 字符权限校验 + * @param {Array} value 校验值 + * @returns {Boolean} + */ +export function checkPermi(value) { + if (value && value instanceof Array && value.length > 0) { + const permissions = store.getters && store.getters.permissions + const permissionDatas = value + const all_permission = "*:*:*"; + + const hasPermission = permissions.some(permission => { + return all_permission === permission || permissionDatas.includes(permission) + }) + + return hasPermission; + + } else { + console.error(`need roles! Like checkPermi="['system:user:add','system:user:edit']"`) + return false + } +} + +/** + * 角色权限校验 + * @param {Array} value 校验值 + * @returns {Boolean} + */ +export function checkRole(value) { + if (value && value instanceof Array && value.length > 0) { + const roles = store.getters && store.getters.roles + const permissionRoles = value + const super_admin = "admin"; + + const hasRole = roles.some(role => { + return super_admin === role || permissionRoles.includes(role) + }) + + return hasRole; + + } else { + console.error(`need roles! Like checkRole="['admin','editor']"`) + return false + } +} \ No newline at end of file diff --git a/zzyl-ui/src/utils/request.js b/zzyl-ui/src/utils/request.js new file mode 100644 index 0000000..ffb0d21 --- /dev/null +++ b/zzyl-ui/src/utils/request.js @@ -0,0 +1,152 @@ +import axios from 'axios' +import { Notification, MessageBox, Message, Loading } from 'element-ui' +import store from '@/store' +import { getToken } from '@/utils/auth' +import errorCode from '@/utils/errorCode' +import { tansParams, blobValidate } from "@/utils/ruoyi"; +import cache from '@/plugins/cache' +import { saveAs } from 'file-saver' + +let downloadLoadingInstance; +// 是否显示重新登录 +export let isRelogin = { show: false }; + +axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8' +// 创建axios实例 +const service = axios.create({ + // axios中请求配置有baseURL选项,表示请求URL公共部分 + baseURL: process.env.VUE_APP_BASE_API, + // 超时 + timeout: 10000 +}) + +// request拦截器 +service.interceptors.request.use(config => { + // 是否需要设置 token + const isToken = (config.headers || {}).isToken === false + // 是否需要防止数据重复提交 + const isRepeatSubmit = (config.headers || {}).repeatSubmit === false + if (getToken() && !isToken) { + config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改 + } + // get请求映射params参数 + if (config.method === 'get' && config.params) { + let url = config.url + '?' + tansParams(config.params); + url = url.slice(0, -1); + config.params = {}; + config.url = url; + } + if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) { + const requestObj = { + url: config.url, + data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data, + time: new Date().getTime() + } + const requestSize = Object.keys(JSON.stringify(requestObj)).length; // 请求数据大小 + const limitSize = 5 * 1024 * 1024; // 限制存放数据5M + if (requestSize >= limitSize) { + console.warn(`[${config.url}]: ` + '请求数据大小超出允许的5M限制,无法进行防重复提交验证。') + return config; + } + const sessionObj = cache.session.getJSON('sessionObj') + if (sessionObj === undefined || sessionObj === null || sessionObj === '') { + cache.session.setJSON('sessionObj', requestObj) + } else { + const s_url = sessionObj.url; // 请求地址 + const s_data = sessionObj.data; // 请求数据 + const s_time = sessionObj.time; // 请求时间 + const interval = 1000; // 间隔时间(ms),小于此时间视为重复提交 + if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) { + const message = '数据正在处理,请勿重复提交'; + console.warn(`[${s_url}]: ` + message) + return Promise.reject(new Error(message)) + } else { + cache.session.setJSON('sessionObj', requestObj) + } + } + } + return config +}, error => { + console.log(error) + Promise.reject(error) +}) + +// 响应拦截器 +service.interceptors.response.use(res => { + // 未设置状态码则默认成功状态 + const code = res.data.code || 200; + // 获取错误信息 + const msg = errorCode[code] || res.data.msg || errorCode['default'] + // 二进制数据则直接返回 + if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') { + return res.data + } + if (code === 401) { + if (!isRelogin.show) { + isRelogin.show = true; + MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' }).then(() => { + isRelogin.show = false; + store.dispatch('LogOut').then(() => { + location.href = '/index'; + }) + }).catch(() => { + isRelogin.show = false; + }); + } + return Promise.reject('无效的会话,或者会话已过期,请重新登录。') + } else if (code === 500) { + Message({ message: msg, type: 'error' }) + return Promise.reject(new Error(msg)) + } else if (code === 601) { + Message({ message: msg, type: 'warning' }) + return Promise.reject('error') + } else if (code !== 200) { + Notification.error({ title: msg }) + return Promise.reject('error') + } else { + return res.data + } + }, + error => { + console.log('err' + error) + let { message } = error; + if (message == "Network Error") { + message = "后端接口连接异常"; + } else if (message.includes("timeout")) { + message = "系统接口请求超时"; + } else if (message.includes("Request failed with status code")) { + message = "系统接口" + message.substr(message.length - 3) + "异常"; + } + Message({ message: message, type: 'error', duration: 5 * 1000 }) + return Promise.reject(error) + } +) + +// 通用下载方法 +export function download(url, params, filename, config) { + downloadLoadingInstance = Loading.service({ text: "正在下载数据,请稍候", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)", }) + return service.post(url, params, { + transformRequest: [(params) => { return tansParams(params) }], + headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, + responseType: 'blob', + ...config + }).then(async (data) => { + const isBlob = blobValidate(data); + if (isBlob) { + const blob = new Blob([data]) + saveAs(blob, filename) + } else { + const resText = await data.text(); + const rspObj = JSON.parse(resText); + const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default'] + Message.error(errMsg); + } + downloadLoadingInstance.close(); + }).catch((r) => { + console.error(r) + Message.error('下载文件出现错误,请联系管理员!') + downloadLoadingInstance.close(); + }) +} + +export default service diff --git a/zzyl-ui/src/utils/ruoyi.js b/zzyl-ui/src/utils/ruoyi.js new file mode 100644 index 0000000..44bf9c4 --- /dev/null +++ b/zzyl-ui/src/utils/ruoyi.js @@ -0,0 +1,233 @@ + + +/** + * 通用js方法封装处理 + * Copyright (c) 2019 ruoyi + */ + +// 日期格式化 +export function parseTime(time, pattern) { + if (arguments.length === 0 || !time) { + return null + } + const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}' + let date + if (typeof time === 'object') { + date = time + } else { + if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) { + time = parseInt(time) + } else if (typeof time === 'string') { + time = time.replace(new RegExp(/-/gm), '/').replace('T', ' ').replace(new RegExp(/\.[\d]{3}/gm), ''); + } + if ((typeof time === 'number') && (time.toString().length === 10)) { + time = time * 1000 + } + date = new Date(time) + } + const formatObj = { + y: date.getFullYear(), + m: date.getMonth() + 1, + d: date.getDate(), + h: date.getHours(), + i: date.getMinutes(), + s: date.getSeconds(), + a: date.getDay() + } + const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => { + let value = formatObj[key] + // Note: getDay() returns 0 on Sunday + if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] } + if (result.length > 0 && value < 10) { + value = '0' + value + } + return value || 0 + }) + return time_str +} + +// 表单重置 +export function resetForm(refName) { + if (this.$refs[refName]) { + this.$refs[refName].resetFields(); + } +} + +// 添加日期范围 +export function addDateRange(params, dateRange, propName) { + let search = params; + search.params = typeof (search.params) === 'object' && search.params !== null && !Array.isArray(search.params) ? search.params : {}; + dateRange = Array.isArray(dateRange) ? dateRange : []; + if (typeof (propName) === 'undefined') { + search.params['beginTime'] = dateRange[0]; + search.params['endTime'] = dateRange[1]; + } else { + search.params['begin' + propName] = dateRange[0]; + search.params['end' + propName] = dateRange[1]; + } + return search; +} + +// 回显数据字典 +export function selectDictLabel(datas, value) { + if (value === undefined) { + return ""; + } + var actions = []; + Object.keys(datas).some((key) => { + if (datas[key].value == ('' + value)) { + actions.push(datas[key].label); + return true; + } + }) + if (actions.length === 0) { + actions.push(value); + } + return actions.join(''); +} + +// 回显数据字典(字符串、数组) +export function selectDictLabels(datas, value, separator) { + if (value === undefined || value.length ===0) { + return ""; + } + if (Array.isArray(value)) { + value = value.join(","); + } + var actions = []; + var currentSeparator = undefined === separator ? "," : separator; + var temp = value.split(currentSeparator); + Object.keys(value.split(currentSeparator)).some((val) => { + var match = false; + Object.keys(datas).some((key) => { + if (datas[key].value == ('' + temp[val])) { + actions.push(datas[key].label + currentSeparator); + match = true; + } + }) + if (!match) { + actions.push(temp[val] + currentSeparator); + } + }) + return actions.join('').substring(0, actions.join('').length - 1); +} + +// 字符串格式化(%s ) +export function sprintf(str) { + var args = arguments, flag = true, i = 1; + str = str.replace(/%s/g, function () { + var arg = args[i++]; + if (typeof arg === 'undefined') { + flag = false; + return ''; + } + return arg; + }); + return flag ? str : ''; +} + +// 转换字符串,undefined,null等转化为"" +export function parseStrEmpty(str) { + if (!str || str == "undefined" || str == "null") { + return ""; + } + return str; +} + +// 数据合并 +export function mergeRecursive(source, target) { + for (var p in target) { + try { + if (target[p].constructor == Object) { + source[p] = mergeRecursive(source[p], target[p]); + } else { + source[p] = target[p]; + } + } catch (e) { + source[p] = target[p]; + } + } + return source; +}; + +/** + * 构造树型结构数据 + * @param {*} data 数据源 + * @param {*} id id字段 默认 'id' + * @param {*} parentId 父节点字段 默认 'parentId' + * @param {*} children 孩子节点字段 默认 'children' + */ +export function handleTree(data, id, parentId, children) { + let config = { + id: id || 'id', + parentId: parentId || 'parentId', + childrenList: children || 'children' + }; + + var childrenListMap = {}; + var nodeIds = {}; + var tree = []; + + for (let d of data) { + let parentId = d[config.parentId]; + if (childrenListMap[parentId] == null) { + childrenListMap[parentId] = []; + } + nodeIds[d[config.id]] = d; + childrenListMap[parentId].push(d); + } + + for (let d of data) { + let parentId = d[config.parentId]; + if (nodeIds[parentId] == null) { + tree.push(d); + } + } + + for (let t of tree) { + adaptToChildrenList(t); + } + + function adaptToChildrenList(o) { + if (childrenListMap[o[config.id]] !== null) { + o[config.childrenList] = childrenListMap[o[config.id]]; + } + if (o[config.childrenList]) { + for (let c of o[config.childrenList]) { + adaptToChildrenList(c); + } + } + } + return tree; +} + +/** +* 参数处理 +* @param {*} params 参数 +*/ +export function tansParams(params) { + let result = '' + for (const propName of Object.keys(params)) { + const value = params[propName]; + var part = encodeURIComponent(propName) + "="; + if (value !== null && value !== "" && typeof (value) !== "undefined") { + if (typeof value === 'object') { + for (const key of Object.keys(value)) { + if (value[key] !== null && value[key] !== "" && typeof (value[key]) !== 'undefined') { + let params = propName + '[' + key + ']'; + var subPart = encodeURIComponent(params) + "="; + result += subPart + encodeURIComponent(value[key]) + "&"; + } + } + } else { + result += part + encodeURIComponent(value) + "&"; + } + } + } + return result +} + +// 验证是否为blob格式 +export function blobValidate(data) { + return data.type !== 'application/json' +} diff --git a/zzyl-ui/src/utils/scroll-to.js b/zzyl-ui/src/utils/scroll-to.js new file mode 100644 index 0000000..c5d8e04 --- /dev/null +++ b/zzyl-ui/src/utils/scroll-to.js @@ -0,0 +1,58 @@ +Math.easeInOutQuad = function(t, b, c, d) { + t /= d / 2 + if (t < 1) { + return c / 2 * t * t + b + } + t-- + return -c / 2 * (t * (t - 2) - 1) + b +} + +// requestAnimationFrame for Smart Animating http://goo.gl/sx5sts +var requestAnimFrame = (function() { + return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback) { window.setTimeout(callback, 1000 / 60) } +})() + +/** + * Because it's so fucking difficult to detect the scrolling element, just move them all + * @param {number} amount + */ +function move(amount) { + document.documentElement.scrollTop = amount + document.body.parentNode.scrollTop = amount + document.body.scrollTop = amount +} + +function position() { + return document.documentElement.scrollTop || document.body.parentNode.scrollTop || document.body.scrollTop +} + +/** + * @param {number} to + * @param {number} duration + * @param {Function} callback + */ +export function scrollTo(to, duration, callback) { + const start = position() + const change = to - start + const increment = 20 + let currentTime = 0 + duration = (typeof (duration) === 'undefined') ? 500 : duration + var animateScroll = function() { + // increment the time + currentTime += increment + // find the value with the quadratic in-out easing function + var val = Math.easeInOutQuad(currentTime, start, change, duration) + // move the document.body + move(val) + // do the animation unless its over + if (currentTime < duration) { + requestAnimFrame(animateScroll) + } else { + if (callback && typeof (callback) === 'function') { + // the animation is done so lets callback + callback() + } + } + } + animateScroll() +} diff --git a/zzyl-ui/src/utils/validate.js b/zzyl-ui/src/utils/validate.js new file mode 100644 index 0000000..57a568e --- /dev/null +++ b/zzyl-ui/src/utils/validate.js @@ -0,0 +1,80 @@ +/** + * @param {string} path + * @returns {Boolean} + */ +export function isExternal(path) { + return /^(https?:|mailto:|tel:)/.test(path) +} + +/** + * @param {string} str + * @returns {Boolean} + */ +export function validUsername(str) { + const valid_map = ['admin', 'editor'] + return valid_map.indexOf(str.trim()) >= 0 +} + +/** + * @param {string} url + * @returns {Boolean} + */ +export function validURL(url) { + const reg = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/ + return reg.test(url) +} + +/** + * @param {string} str + * @returns {Boolean} + */ +export function validLowerCase(str) { + const reg = /^[a-z]+$/ + return reg.test(str) +} + +/** + * @param {string} str + * @returns {Boolean} + */ +export function validUpperCase(str) { + const reg = /^[A-Z]+$/ + return reg.test(str) +} + +/** + * @param {string} str + * @returns {Boolean} + */ +export function validAlphabets(str) { + const reg = /^[A-Za-z]+$/ + return reg.test(str) +} + +/** + * @param {string} email + * @returns {Boolean} + */ +export function validEmail(email) { + const reg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ + return reg.test(email) +} + +/** + * @param {string} str + * @returns {Boolean} + */ +export function isString(str) { + return typeof str === 'string' || str instanceof String; +} + +/** + * @param {Array} arg + * @returns {Boolean} + */ +export function isArray(arg) { + if (typeof Array.isArray === 'undefined') { + return Object.prototype.toString.call(arg) === '[object Array]' + } + return Array.isArray(arg) +} diff --git a/zzyl-ui/src/views/dashboard/BarChart.vue b/zzyl-ui/src/views/dashboard/BarChart.vue new file mode 100644 index 0000000..88e7ef6 --- /dev/null +++ b/zzyl-ui/src/views/dashboard/BarChart.vue @@ -0,0 +1,102 @@ + + + diff --git a/zzyl-ui/src/views/dashboard/LineChart.vue b/zzyl-ui/src/views/dashboard/LineChart.vue new file mode 100644 index 0000000..702ff73 --- /dev/null +++ b/zzyl-ui/src/views/dashboard/LineChart.vue @@ -0,0 +1,135 @@ + + + diff --git a/zzyl-ui/src/views/dashboard/PanelGroup.vue b/zzyl-ui/src/views/dashboard/PanelGroup.vue new file mode 100644 index 0000000..1a1081f --- /dev/null +++ b/zzyl-ui/src/views/dashboard/PanelGroup.vue @@ -0,0 +1,181 @@ + + + + + diff --git a/zzyl-ui/src/views/dashboard/PieChart.vue b/zzyl-ui/src/views/dashboard/PieChart.vue new file mode 100644 index 0000000..63f0d84 --- /dev/null +++ b/zzyl-ui/src/views/dashboard/PieChart.vue @@ -0,0 +1,79 @@ + + + diff --git a/zzyl-ui/src/views/dashboard/RaddarChart.vue b/zzyl-ui/src/views/dashboard/RaddarChart.vue new file mode 100644 index 0000000..312e018 --- /dev/null +++ b/zzyl-ui/src/views/dashboard/RaddarChart.vue @@ -0,0 +1,116 @@ + + + diff --git a/zzyl-ui/src/views/dashboard/mixins/resize.js b/zzyl-ui/src/views/dashboard/mixins/resize.js new file mode 100644 index 0000000..b1e76e9 --- /dev/null +++ b/zzyl-ui/src/views/dashboard/mixins/resize.js @@ -0,0 +1,56 @@ +import { debounce } from '@/utils' + +export default { + data() { + return { + $_sidebarElm: null, + $_resizeHandler: null + } + }, + mounted() { + this.initListener() + }, + activated() { + if (!this.$_resizeHandler) { + // avoid duplication init + this.initListener() + } + + // when keep-alive chart activated, auto resize + this.resize() + }, + beforeDestroy() { + this.destroyListener() + }, + deactivated() { + this.destroyListener() + }, + methods: { + // use $_ for mixins properties + // https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential + $_sidebarResizeHandler(e) { + if (e.propertyName === 'width') { + this.$_resizeHandler() + } + }, + initListener() { + this.$_resizeHandler = debounce(() => { + this.resize() + }, 100) + window.addEventListener('resize', this.$_resizeHandler) + + this.$_sidebarElm = document.getElementsByClassName('sidebar-container')[0] + this.$_sidebarElm && this.$_sidebarElm.addEventListener('transitionend', this.$_sidebarResizeHandler) + }, + destroyListener() { + window.removeEventListener('resize', this.$_resizeHandler) + this.$_resizeHandler = null + + this.$_sidebarElm && this.$_sidebarElm.removeEventListener('transitionend', this.$_sidebarResizeHandler) + }, + resize() { + const { chart } = this + chart && chart.resize() + } + } +} diff --git a/zzyl-ui/src/views/error/401.vue b/zzyl-ui/src/views/error/401.vue new file mode 100644 index 0000000..448b6ec --- /dev/null +++ b/zzyl-ui/src/views/error/401.vue @@ -0,0 +1,88 @@ + + + + + diff --git a/zzyl-ui/src/views/error/404.vue b/zzyl-ui/src/views/error/404.vue new file mode 100644 index 0000000..96f075c --- /dev/null +++ b/zzyl-ui/src/views/error/404.vue @@ -0,0 +1,233 @@ + + + + + diff --git a/zzyl-ui/src/views/index.vue b/zzyl-ui/src/views/index.vue new file mode 100644 index 0000000..8081a92 --- /dev/null +++ b/zzyl-ui/src/views/index.vue @@ -0,0 +1,1097 @@ + + + + + + diff --git a/zzyl-ui/src/views/index_v1.vue b/zzyl-ui/src/views/index_v1.vue new file mode 100644 index 0000000..d2d2ec6 --- /dev/null +++ b/zzyl-ui/src/views/index_v1.vue @@ -0,0 +1,98 @@ + + + + + diff --git a/zzyl-ui/src/views/login.vue b/zzyl-ui/src/views/login.vue new file mode 100644 index 0000000..b16097a --- /dev/null +++ b/zzyl-ui/src/views/login.vue @@ -0,0 +1,219 @@ + + + + + diff --git a/zzyl-ui/src/views/monitor/cache/index.vue b/zzyl-ui/src/views/monitor/cache/index.vue new file mode 100644 index 0000000..8d2f378 --- /dev/null +++ b/zzyl-ui/src/views/monitor/cache/index.vue @@ -0,0 +1,148 @@ + + + diff --git a/zzyl-ui/src/views/monitor/cache/list.vue b/zzyl-ui/src/views/monitor/cache/list.vue new file mode 100644 index 0000000..29a7c74 --- /dev/null +++ b/zzyl-ui/src/views/monitor/cache/list.vue @@ -0,0 +1,241 @@ + + + diff --git a/zzyl-ui/src/views/monitor/druid/index.vue b/zzyl-ui/src/views/monitor/druid/index.vue new file mode 100644 index 0000000..c6ad585 --- /dev/null +++ b/zzyl-ui/src/views/monitor/druid/index.vue @@ -0,0 +1,15 @@ + + diff --git a/zzyl-ui/src/views/monitor/job/index.vue b/zzyl-ui/src/views/monitor/job/index.vue new file mode 100644 index 0000000..892c727 --- /dev/null +++ b/zzyl-ui/src/views/monitor/job/index.vue @@ -0,0 +1,513 @@ + + + diff --git a/zzyl-ui/src/views/monitor/job/log.vue b/zzyl-ui/src/views/monitor/job/log.vue new file mode 100644 index 0000000..60bee1d --- /dev/null +++ b/zzyl-ui/src/views/monitor/job/log.vue @@ -0,0 +1,295 @@ + + + diff --git a/zzyl-ui/src/views/monitor/logininfor/index.vue b/zzyl-ui/src/views/monitor/logininfor/index.vue new file mode 100644 index 0000000..d6af834 --- /dev/null +++ b/zzyl-ui/src/views/monitor/logininfor/index.vue @@ -0,0 +1,246 @@ + + + + diff --git a/zzyl-ui/src/views/monitor/online/index.vue b/zzyl-ui/src/views/monitor/online/index.vue new file mode 100644 index 0000000..ad613c9 --- /dev/null +++ b/zzyl-ui/src/views/monitor/online/index.vue @@ -0,0 +1,122 @@ + + + + diff --git a/zzyl-ui/src/views/monitor/operlog/index.vue b/zzyl-ui/src/views/monitor/operlog/index.vue new file mode 100644 index 0000000..4a1828f --- /dev/null +++ b/zzyl-ui/src/views/monitor/operlog/index.vue @@ -0,0 +1,323 @@ + + + + diff --git a/zzyl-ui/src/views/monitor/server/index.vue b/zzyl-ui/src/views/monitor/server/index.vue new file mode 100644 index 0000000..15ffc9a --- /dev/null +++ b/zzyl-ui/src/views/monitor/server/index.vue @@ -0,0 +1,207 @@ + + + diff --git a/zzyl-ui/src/views/redirect.vue b/zzyl-ui/src/views/redirect.vue new file mode 100644 index 0000000..db4c1d6 --- /dev/null +++ b/zzyl-ui/src/views/redirect.vue @@ -0,0 +1,12 @@ + diff --git a/zzyl-ui/src/views/register.vue b/zzyl-ui/src/views/register.vue new file mode 100644 index 0000000..7bf6f43 --- /dev/null +++ b/zzyl-ui/src/views/register.vue @@ -0,0 +1,210 @@ + + + + + diff --git a/zzyl-ui/src/views/system/config/index.vue b/zzyl-ui/src/views/system/config/index.vue new file mode 100644 index 0000000..3ab81fc --- /dev/null +++ b/zzyl-ui/src/views/system/config/index.vue @@ -0,0 +1,343 @@ + + + diff --git a/zzyl-ui/src/views/system/dept/index.vue b/zzyl-ui/src/views/system/dept/index.vue new file mode 100644 index 0000000..e502b4e --- /dev/null +++ b/zzyl-ui/src/views/system/dept/index.vue @@ -0,0 +1,340 @@ + + + diff --git a/zzyl-ui/src/views/system/dict/data.vue b/zzyl-ui/src/views/system/dict/data.vue new file mode 100644 index 0000000..3befe4a --- /dev/null +++ b/zzyl-ui/src/views/system/dict/data.vue @@ -0,0 +1,402 @@ + + + \ No newline at end of file diff --git a/zzyl-ui/src/views/system/dict/index.vue b/zzyl-ui/src/views/system/dict/index.vue new file mode 100644 index 0000000..6ca5457 --- /dev/null +++ b/zzyl-ui/src/views/system/dict/index.vue @@ -0,0 +1,347 @@ + + + \ No newline at end of file diff --git a/zzyl-ui/src/views/system/menu/index.vue b/zzyl-ui/src/views/system/menu/index.vue new file mode 100644 index 0000000..c703fa0 --- /dev/null +++ b/zzyl-ui/src/views/system/menu/index.vue @@ -0,0 +1,452 @@ + + + diff --git a/zzyl-ui/src/views/system/notice/index.vue b/zzyl-ui/src/views/system/notice/index.vue new file mode 100644 index 0000000..7982b54 --- /dev/null +++ b/zzyl-ui/src/views/system/notice/index.vue @@ -0,0 +1,312 @@ + + + diff --git a/zzyl-ui/src/views/system/post/index.vue b/zzyl-ui/src/views/system/post/index.vue new file mode 100644 index 0000000..444bf63 --- /dev/null +++ b/zzyl-ui/src/views/system/post/index.vue @@ -0,0 +1,309 @@ + + + diff --git a/zzyl-ui/src/views/system/role/authUser.vue b/zzyl-ui/src/views/system/role/authUser.vue new file mode 100644 index 0000000..147aa33 --- /dev/null +++ b/zzyl-ui/src/views/system/role/authUser.vue @@ -0,0 +1,199 @@ + + + \ No newline at end of file diff --git a/zzyl-ui/src/views/system/role/index.vue b/zzyl-ui/src/views/system/role/index.vue new file mode 100644 index 0000000..fb3b5ef --- /dev/null +++ b/zzyl-ui/src/views/system/role/index.vue @@ -0,0 +1,605 @@ + + + \ No newline at end of file diff --git a/zzyl-ui/src/views/system/role/selectUser.vue b/zzyl-ui/src/views/system/role/selectUser.vue new file mode 100644 index 0000000..10a5365 --- /dev/null +++ b/zzyl-ui/src/views/system/role/selectUser.vue @@ -0,0 +1,136 @@ + + + diff --git a/zzyl-ui/src/views/system/user/authRole.vue b/zzyl-ui/src/views/system/user/authRole.vue new file mode 100644 index 0000000..943710e --- /dev/null +++ b/zzyl-ui/src/views/system/user/authRole.vue @@ -0,0 +1,117 @@ + + + \ No newline at end of file diff --git a/zzyl-ui/src/views/system/user/index.vue b/zzyl-ui/src/views/system/user/index.vue new file mode 100644 index 0000000..6b2a0aa --- /dev/null +++ b/zzyl-ui/src/views/system/user/index.vue @@ -0,0 +1,676 @@ + + + \ No newline at end of file diff --git a/zzyl-ui/src/views/system/user/profile/index.vue b/zzyl-ui/src/views/system/user/profile/index.vue new file mode 100644 index 0000000..529c564 --- /dev/null +++ b/zzyl-ui/src/views/system/user/profile/index.vue @@ -0,0 +1,91 @@ + + + diff --git a/zzyl-ui/src/views/system/user/profile/resetPwd.vue b/zzyl-ui/src/views/system/user/profile/resetPwd.vue new file mode 100644 index 0000000..f329e6e --- /dev/null +++ b/zzyl-ui/src/views/system/user/profile/resetPwd.vue @@ -0,0 +1,69 @@ + + + diff --git a/zzyl-ui/src/views/system/user/profile/userAvatar.vue b/zzyl-ui/src/views/system/user/profile/userAvatar.vue new file mode 100644 index 0000000..cbf3ca1 --- /dev/null +++ b/zzyl-ui/src/views/system/user/profile/userAvatar.vue @@ -0,0 +1,184 @@ + + + + diff --git a/zzyl-ui/src/views/system/user/profile/userInfo.vue b/zzyl-ui/src/views/system/user/profile/userInfo.vue new file mode 100644 index 0000000..c970dc9 --- /dev/null +++ b/zzyl-ui/src/views/system/user/profile/userInfo.vue @@ -0,0 +1,88 @@ + + + diff --git a/zzyl-ui/src/views/tool/build/CodeTypeDialog.vue b/zzyl-ui/src/views/tool/build/CodeTypeDialog.vue new file mode 100644 index 0000000..b5c2e2e --- /dev/null +++ b/zzyl-ui/src/views/tool/build/CodeTypeDialog.vue @@ -0,0 +1,106 @@ + + diff --git a/zzyl-ui/src/views/tool/build/DraggableItem.vue b/zzyl-ui/src/views/tool/build/DraggableItem.vue new file mode 100644 index 0000000..e881778 --- /dev/null +++ b/zzyl-ui/src/views/tool/build/DraggableItem.vue @@ -0,0 +1,100 @@ + diff --git a/zzyl-ui/src/views/tool/build/IconsDialog.vue b/zzyl-ui/src/views/tool/build/IconsDialog.vue new file mode 100644 index 0000000..958be50 --- /dev/null +++ b/zzyl-ui/src/views/tool/build/IconsDialog.vue @@ -0,0 +1,123 @@ + + + diff --git a/zzyl-ui/src/views/tool/build/RightPanel.vue b/zzyl-ui/src/views/tool/build/RightPanel.vue new file mode 100644 index 0000000..c2760eb --- /dev/null +++ b/zzyl-ui/src/views/tool/build/RightPanel.vue @@ -0,0 +1,946 @@ + + + + + diff --git a/zzyl-ui/src/views/tool/build/TreeNodeDialog.vue b/zzyl-ui/src/views/tool/build/TreeNodeDialog.vue new file mode 100644 index 0000000..fa7f0b2 --- /dev/null +++ b/zzyl-ui/src/views/tool/build/TreeNodeDialog.vue @@ -0,0 +1,149 @@ + + diff --git a/zzyl-ui/src/views/tool/build/index.vue b/zzyl-ui/src/views/tool/build/index.vue new file mode 100644 index 0000000..2bd298b --- /dev/null +++ b/zzyl-ui/src/views/tool/build/index.vue @@ -0,0 +1,768 @@ + + + + + diff --git a/zzyl-ui/src/views/tool/gen/basicInfoForm.vue b/zzyl-ui/src/views/tool/gen/basicInfoForm.vue new file mode 100644 index 0000000..7029529 --- /dev/null +++ b/zzyl-ui/src/views/tool/gen/basicInfoForm.vue @@ -0,0 +1,60 @@ + + + diff --git a/zzyl-ui/src/views/tool/gen/createTable.vue b/zzyl-ui/src/views/tool/gen/createTable.vue new file mode 100644 index 0000000..f914b5d --- /dev/null +++ b/zzyl-ui/src/views/tool/gen/createTable.vue @@ -0,0 +1,45 @@ + + + diff --git a/zzyl-ui/src/views/tool/gen/editTable.vue b/zzyl-ui/src/views/tool/gen/editTable.vue new file mode 100644 index 0000000..951497a --- /dev/null +++ b/zzyl-ui/src/views/tool/gen/editTable.vue @@ -0,0 +1,234 @@ + + + diff --git a/zzyl-ui/src/views/tool/gen/genInfoForm.vue b/zzyl-ui/src/views/tool/gen/genInfoForm.vue new file mode 100644 index 0000000..98daf6d --- /dev/null +++ b/zzyl-ui/src/views/tool/gen/genInfoForm.vue @@ -0,0 +1,312 @@ + + + diff --git a/zzyl-ui/src/views/tool/gen/importTable.vue b/zzyl-ui/src/views/tool/gen/importTable.vue new file mode 100644 index 0000000..3ea9532 --- /dev/null +++ b/zzyl-ui/src/views/tool/gen/importTable.vue @@ -0,0 +1,120 @@ + + + diff --git a/zzyl-ui/src/views/tool/gen/index.vue b/zzyl-ui/src/views/tool/gen/index.vue new file mode 100644 index 0000000..9237c30 --- /dev/null +++ b/zzyl-ui/src/views/tool/gen/index.vue @@ -0,0 +1,354 @@ + + + diff --git a/zzyl-ui/src/views/tool/swagger/index.vue b/zzyl-ui/src/views/tool/swagger/index.vue new file mode 100644 index 0000000..b8becc6 --- /dev/null +++ b/zzyl-ui/src/views/tool/swagger/index.vue @@ -0,0 +1,15 @@ + + diff --git a/zzyl-ui/vue.config.js b/zzyl-ui/vue.config.js new file mode 100644 index 0000000..40b6822 --- /dev/null +++ b/zzyl-ui/vue.config.js @@ -0,0 +1,130 @@ +'use strict' +const path = require('path') + +function resolve(dir) { + return path.join(__dirname, dir) +} + +const CompressionPlugin = require('compression-webpack-plugin') + +const name = process.env.VUE_APP_TITLE || '中州养老' // 网页标题 + +const port = process.env.port || process.env.npm_config_port || 80 // 端口 + +// vue.config.js 配置说明 +//官方vue.config.js 参考文档 https://cli.vuejs.org/zh/config/#css-loaderoptions +// 这里只列一部分,具体配置参考文档 +module.exports = { + // 部署生产环境和开发环境下的URL。 + // 默认情况下,Vue CLI 会假设你的应用是被部署在一个域名的根路径上 + // 例如 https://www.ruoyi.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.ruoyi.vip/admin/,则设置 baseUrl 为 /admin/。 + publicPath: process.env.NODE_ENV === "production" ? "/" : "/", + // 在npm run build 或 yarn build 时 ,生成文件的目录名称(要和baseUrl的生产环境路径一致)(默认dist) + outputDir: 'dist', + // 用于放置生成的静态资源 (js、css、img、fonts) 的;(项目打包之后,静态资源会放在这个文件夹下) + assetsDir: 'static', + // 是否开启eslint保存检测,有效值:ture | false | 'error' + lintOnSave: process.env.NODE_ENV === 'development', + // 如果你不需要生产环境的 source map,可以将其设置为 false 以加速生产环境构建。 + productionSourceMap: false, + // webpack-dev-server 相关配置 + devServer: { + host: '0.0.0.0', + port: port, + open: true, + proxy: { + // detail: https://cli.vuejs.org/config/#devserver-proxy + [process.env.VUE_APP_BASE_API]: { + target: `http://localhost:8080`, + changeOrigin: true, + pathRewrite: { + ['^' + process.env.VUE_APP_BASE_API]: '' + } + } + }, + disableHostCheck: true + }, + css: { + loaderOptions: { + sass: { + sassOptions: { outputStyle: "expanded" } + } + } + }, + configureWebpack: { + name: name, + resolve: { + alias: { + '@': resolve('src') + } + }, + plugins: [ + // http://doc.ruoyi.vip/ruoyi-vue/other/faq.html#使用gzip解压缩静态文件 + new CompressionPlugin({ + cache: false, // 不启用文件缓存 + test: /\.(js|css|html|jpe?g|png|gif|svg)?$/i, // 压缩文件格式 + filename: '[path][base].gz[query]', // 压缩后的文件名 + algorithm: 'gzip', // 使用gzip压缩 + minRatio: 0.8, // 压缩比例,小于 80% 的文件不会被压缩 + deleteOriginalAssets: false // 压缩后删除原文件 + }) + ], + }, + chainWebpack(config) { + config.plugins.delete('preload') // TODO: need test + config.plugins.delete('prefetch') // TODO: need test + + // set svg-sprite-loader + config.module + .rule('svg') + .exclude.add(resolve('src/assets/icons')) + .end() + config.module + .rule('icons') + .test(/\.svg$/) + .include.add(resolve('src/assets/icons')) + .end() + .use('svg-sprite-loader') + .loader('svg-sprite-loader') + .options({ + symbolId: 'icon-[name]' + }) + .end() + + config.when(process.env.NODE_ENV !== 'development', config => { + config + .plugin('ScriptExtHtmlWebpackPlugin') + .after('html') + .use('script-ext-html-webpack-plugin', [{ + // `runtime` must same as runtimeChunk name. default is `runtime` + inline: /runtime\..*\.js$/ + }]) + .end() + + config.optimization.splitChunks({ + chunks: 'all', + cacheGroups: { + libs: { + name: 'chunk-libs', + test: /[\\/]node_modules[\\/]/, + priority: 10, + chunks: 'initial' // only package third parties that are initially dependent + }, + elementUI: { + name: 'chunk-elementUI', // split elementUI into a single package + test: /[\\/]node_modules[\\/]_?element-ui(.*)/, // in order to adapt to cnpm + priority: 20 // the weight needs to be larger than libs and app or it will be packaged into libs or app + }, + commons: { + name: 'chunk-commons', + test: resolve('src/components'), // can customize your rules + minChunks: 3, // minimum common number + priority: 5, + reuseExistingChunk: true + } + } + }) + config.optimization.runtimeChunk('single') + }) + } +}